forked from OSchip/llvm-project
				
			Add diagnostic for constructs like "va_arg(l, float)" which have undefined behavior. PR10201.
llvm-svn: 134926
This commit is contained in:
		
							parent
							
								
									8532db2ec4
								
							
						
					
					
						commit
						6290ae476e
					
				| 
						 | 
					@ -4208,6 +4208,9 @@ def err_second_parameter_to_va_arg_abstract: Error<
 | 
				
			||||||
def warn_second_parameter_to_va_arg_not_pod : Warning<
 | 
					def warn_second_parameter_to_va_arg_not_pod : Warning<
 | 
				
			||||||
  "second argument to 'va_arg' is of non-POD type %0">,
 | 
					  "second argument to 'va_arg' is of non-POD type %0">,
 | 
				
			||||||
  InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
 | 
					  InGroup<DiagGroup<"non-pod-varargs">>, DefaultError;
 | 
				
			||||||
 | 
					def warn_second_parameter_to_va_arg_never_compatible : Warning<
 | 
				
			||||||
 | 
					  "second argument to 'va_arg' is of promotable type %0; this va_arg has "
 | 
				
			||||||
 | 
					  "undefined behavior because arguments will be promoted to %1">;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def warn_return_missing_expr : Warning<
 | 
					def warn_return_missing_expr : Warning<
 | 
				
			||||||
  "non-void %select{function|method}1 %0 should return a value">, DefaultError,
 | 
					  "non-void %select{function|method}1 %0 should return a value">, DefaultError,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8570,6 +8570,23 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
 | 
				
			||||||
          diag::warn_second_parameter_to_va_arg_not_pod)
 | 
					          diag::warn_second_parameter_to_va_arg_not_pod)
 | 
				
			||||||
        << TInfo->getType()
 | 
					        << TInfo->getType()
 | 
				
			||||||
        << TInfo->getTypeLoc().getSourceRange();
 | 
					        << TInfo->getTypeLoc().getSourceRange();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Check for va_arg where arguments of the given type will be promoted
 | 
				
			||||||
 | 
					    // (i.e. this va_arg is guaranteed to have undefined behavior).
 | 
				
			||||||
 | 
					    QualType PromoteType;
 | 
				
			||||||
 | 
					    if (TInfo->getType()->isPromotableIntegerType()) {
 | 
				
			||||||
 | 
					      PromoteType = Context.getPromotedIntegerType(TInfo->getType());
 | 
				
			||||||
 | 
					      if (Context.typesAreCompatible(PromoteType, TInfo->getType()))
 | 
				
			||||||
 | 
					        PromoteType = QualType();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (TInfo->getType()->isSpecificBuiltinType(BuiltinType::Float))
 | 
				
			||||||
 | 
					      PromoteType = Context.DoubleTy;
 | 
				
			||||||
 | 
					    if (!PromoteType.isNull())
 | 
				
			||||||
 | 
					      Diag(TInfo->getTypeLoc().getBeginLoc(),
 | 
				
			||||||
 | 
					          diag::warn_second_parameter_to_va_arg_never_compatible)
 | 
				
			||||||
 | 
					        << TInfo->getType()
 | 
				
			||||||
 | 
					        << PromoteType
 | 
				
			||||||
 | 
					        << TInfo->getTypeLoc().getSourceRange();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  QualType T = TInfo->getType().getNonLValueExprType(Context);
 | 
					  QualType T = TInfo->getType().getNonLValueExprType(Context);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,3 +67,12 @@ void f8(int a, ...) {
 | 
				
			||||||
  (void)__builtin_va_arg(ap, void); // expected-error {{second argument to 'va_arg' is of incomplete type 'void'}}
 | 
					  (void)__builtin_va_arg(ap, void); // expected-error {{second argument to 'va_arg' is of incomplete type 'void'}}
 | 
				
			||||||
  __builtin_va_end(ap);
 | 
					  __builtin_va_end(ap);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enum E { x = -1, y = 2, z = 10000 };
 | 
				
			||||||
 | 
					void f9(__builtin_va_list args)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    (void)__builtin_va_arg(args, float); // expected-warning {{second argument to 'va_arg' is of promotable type 'float'}}
 | 
				
			||||||
 | 
					    (void)__builtin_va_arg(args, enum E); // Don't warn here in C
 | 
				
			||||||
 | 
					    (void)__builtin_va_arg(args, short); // expected-warning {{second argument to 'va_arg' is of promotable type 'short'}}
 | 
				
			||||||
 | 
					    (void)__builtin_va_arg(args, char); // expected-warning {{second argument to 'va_arg' is of promotable type 'char'}}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue