[cfe-commits] r134926 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/Sema/varargs.c
Eli Friedman
eli.friedman at gmail.com
Mon Jul 11 14:46:00 PDT 2011
Author: efriedma
Date: Mon Jul 11 16:45:59 2011
New Revision: 134926
URL: http://llvm.org/viewvc/llvm-project?rev=134926&view=rev
Log:
Add diagnostic for constructs like "va_arg(l, float)" which have undefined behavior. PR10201.
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/test/Sema/varargs.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=134926&r1=134925&r2=134926&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Jul 11 16:45:59 2011
@@ -4208,6 +4208,9 @@
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,
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=134926&r1=134925&r2=134926&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Mon Jul 11 16:45:59 2011
@@ -8570,6 +8570,23 @@
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);
Modified: cfe/trunk/test/Sema/varargs.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/varargs.c?rev=134926&r1=134925&r2=134926&view=diff
==============================================================================
--- cfe/trunk/test/Sema/varargs.c (original)
+++ cfe/trunk/test/Sema/varargs.c Mon Jul 11 16:45:59 2011
@@ -67,3 +67,12 @@
(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'}}
+}
More information about the cfe-commits
mailing list