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}} +} _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
