r182694 - Warn on va_start() when called with a reference parameter.
Nico Weber
nicolasweber at gmx.de
Fri May 24 16:31:57 PDT 2013
Author: nico
Date: Fri May 24 18:31:57 2013
New Revision: 182694
URL: http://llvm.org/viewvc/llvm-project?rev=182694&view=rev
Log:
Warn on va_start() when called with a reference parameter.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf 18.7p3
explicitly calls this (and some other things) out as undefined.
Also move 2 other existing warnings behind the new -Wvarargs flag.
Added:
cfe/trunk/test/Sema/varargs.cpp
Modified:
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Misc/warning-flags.c
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=182694&r1=182693&r2=182694&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri May 24 18:31:57 2013
@@ -246,6 +246,7 @@ def TautologicalCompare : DiagGroup<"tau
def HeaderHygiene : DiagGroup<"header-hygiene">;
def DuplicateDeclSpecifier : DiagGroup<"duplicate-decl-specifier">;
def CompareDistinctPointerType : DiagGroup<"compare-distinct-pointer-types">;
+def Varargs : DiagGroup<"varargs">;
def Unsequenced : DiagGroup<"unsequenced">;
// GCC name for -Wunsequenced
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=182694&r1=182693&r2=182694&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri May 24 18:31:57 2013
@@ -6090,7 +6090,9 @@ def note_empty_body_on_separate_line : N
def err_va_start_used_in_non_variadic_function : Error<
"'va_start' used in function with fixed args">;
def warn_second_parameter_of_va_start_not_last_named_argument : Warning<
- "second parameter of 'va_start' not last named argument">;
+ "second parameter of 'va_start' not last named argument">, InGroup<Varargs>;
+def warn_va_start_of_reference_type_is_undefined : Warning<
+ "'va_start' has undefined behavior with reference types">, InGroup<Varargs>;
def err_first_argument_to_va_arg_not_of_type_va_list : Error<
"first argument to 'va_arg' is of type %0 and not 'va_list'">;
def err_second_parameter_to_va_arg_incomplete: Error<
@@ -6105,7 +6107,7 @@ def warn_second_parameter_to_va_arg_owne
InGroup<NonPODVarargs>, 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">;
+ "undefined behavior because arguments will be promoted to %1">, InGroup<Varargs>;
def warn_return_missing_expr : Warning<
"non-void %select{function|method}1 %0 should return a value">, DefaultError,
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=182694&r1=182693&r2=182694&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri May 24 18:31:57 2013
@@ -1355,6 +1355,11 @@ bool Sema::SemaBuiltinVAStart(CallExpr *
bool SecondArgIsLastNamedArgument = false;
const Expr *Arg = TheCall->getArg(1)->IgnoreParenCasts();
+ // These are valid if SecondArgIsLastNamedArgument is false after the next
+ // block.
+ QualType Type;
+ SourceLocation ParamLoc;
+
if (const DeclRefExpr *DR = dyn_cast<DeclRefExpr>(Arg)) {
if (const ParmVarDecl *PV = dyn_cast<ParmVarDecl>(DR->getDecl())) {
// FIXME: This isn't correct for methods (results in bogus warning).
@@ -1367,12 +1372,21 @@ bool Sema::SemaBuiltinVAStart(CallExpr *
else
LastArg = *(getCurMethodDecl()->param_end()-1);
SecondArgIsLastNamedArgument = PV == LastArg;
+
+ Type = PV->getType();
+ ParamLoc = PV->getLocation();
}
}
if (!SecondArgIsLastNamedArgument)
Diag(TheCall->getArg(1)->getLocStart(),
diag::warn_second_parameter_of_va_start_not_last_named_argument);
+ else if (Type->isReferenceType()) {
+ Diag(Arg->getLocStart(),
+ diag::warn_va_start_of_reference_type_is_undefined);
+ Diag(ParamLoc, diag::note_parameter_type) << Type;
+ }
+
return false;
}
Modified: cfe/trunk/test/Misc/warning-flags.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Misc/warning-flags.c?rev=182694&r1=182693&r2=182694&view=diff
==============================================================================
--- cfe/trunk/test/Misc/warning-flags.c (original)
+++ cfe/trunk/test/Misc/warning-flags.c Fri May 24 18:31:57 2013
@@ -18,7 +18,7 @@ This test serves two purposes:
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (143):
+CHECK: Warnings without flags (141):
CHECK-NEXT: ext_delete_void_ptr_operand
CHECK-NEXT: ext_enum_friend
CHECK-NEXT: ext_expected_semi_decl_list
@@ -146,8 +146,6 @@ CHECK-NEXT: warn_redeclaration_without
CHECK-NEXT: warn_register_objc_catch_parm
CHECK-NEXT: warn_related_result_type_compatibility_class
CHECK-NEXT: warn_related_result_type_compatibility_protocol
-CHECK-NEXT: warn_second_parameter_of_va_start_not_last_named_argument
-CHECK-NEXT: warn_second_parameter_to_va_arg_never_compatible
CHECK-NEXT: warn_static_inline_explicit_inst_ignored
CHECK-NEXT: warn_static_non_static
CHECK-NEXT: warn_template_export_unsupported
Added: cfe/trunk/test/Sema/varargs.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/varargs.cpp?rev=182694&view=auto
==============================================================================
--- cfe/trunk/test/Sema/varargs.cpp (added)
+++ cfe/trunk/test/Sema/varargs.cpp Fri May 24 18:31:57 2013
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class string;
+void f(const string& s, ...) { // expected-note {{parameter of type 'const string &' is declared here}}
+ __builtin_va_list ap;
+ __builtin_va_start(ap, s); // expected-warning {{'va_start' has undefined behavior with reference types}}
+}
More information about the cfe-commits
mailing list