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<
|
||||
"second argument to 'va_arg' is of non-POD type %0">,
|
||||
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<
|
||||
"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)
|
||||
<< TInfo->getType()
|
||||
<< 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);
|
||||
|
|
|
@ -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'}}
|
||||
__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