def ImplicitConversionFloatingPointToBool :
DiagGroup<"implicit-conversion-floating-point-to-bool">;
def BadArrayNewLength : DiagGroup<"bad-array-new-length">;
+def BuiltinMacroRedefined : DiagGroup<"builtin-macro-redefined">;
def BuiltinRequiresHeader : DiagGroup<"builtin-requires-header">;
def C99Compat : DiagGroup<"c99-compat">;
def CXXCompat: DiagGroup<"c++-compat">;
def pp_poisoning_existing_macro : Warning<"poisoning existing macro">;
def pp_out_of_date_dependency : Warning<
"current file is older than dependency %0">;
-def pp_undef_builtin_macro : Warning<"undefining builtin macro">;
-def pp_redef_builtin_macro : Warning<"redefining builtin macro">,
- InGroup<DiagGroup<"builtin-macro-redefined">>;
+def ext_pp_undef_builtin_macro : ExtWarn<"undefining builtin macro">,
+ InGroup<BuiltinMacroRedefined>;
+def ext_pp_redef_builtin_macro : ExtWarn<"redefining builtin macro">,
+ InGroup<BuiltinMacroRedefined>;
def pp_disabled_macro_expansion : Warning<
"disabled expansion of recursive macro">, DefaultIgnore,
InGroup<DiagGroup<"disabled-macro-expansion">>;
Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
// Fall through on error.
} else if (isDefineUndef && II->getPPKeywordID() == tok::pp_defined) {
- // Error if defining "defined": C99 6.10.8.4.
+ // Error if defining "defined": C99 6.10.8/4, C++ [cpp.predefined]p4.
Diag(MacroNameTok, diag::err_defined_macro_name);
- } else if (isDefineUndef && II->hasMacroDefinition() &&
+ } else if (isDefineUndef == 2 && II->hasMacroDefinition() &&
getMacroInfo(II)->isBuiltinMacro()) {
- // Error if defining "__LINE__" and other builtins: C99 6.10.8.4.
- if (isDefineUndef == 1)
- Diag(MacroNameTok, diag::pp_redef_builtin_macro);
- else
- Diag(MacroNameTok, diag::pp_undef_builtin_macro);
+ // Warn if undefining "__LINE__" and other builtins, per C99 6.10.8/4
+ // and C++ [cpp.predefined]p4], but allow it as an extension.
+ Diag(MacroNameTok, diag::ext_pp_undef_builtin_macro);
+ return;
} else {
// Okay, we got a good identifier node. Return it.
return;
if (!OtherMI->isUsed() && OtherMI->isWarnIfUnused())
Diag(OtherMI->getDefinitionLoc(), diag::pp_macro_not_used);
+ // Warn if defining "__LINE__" and other builtins, per C99 6.10.8/4 and
+ // C++ [cpp.predefined]p4, but allow it as an extension.
+ if (OtherMI->isBuiltinMacro())
+ Diag(MacroNameTok, diag::ext_pp_redef_builtin_macro);
// Macros must be identical. This means all tokens and whitespace
// separation must be the same. C99 6.10.3.2.
- if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
- !MI->isIdenticalTo(*OtherMI, *this)) {
+ else if (!OtherMI->isAllowRedefinitionsWithoutWarning() &&
+ !MI->isIdenticalTo(*OtherMI, *this)) {
Diag(MI->getDefinitionLoc(), diag::ext_pp_macro_redef)
<< MacroNameTok.getIdentifierInfo();
Diag(OtherMI->getDefinitionLoc(), diag::note_previous_definition);
--- /dev/null
+// RUN: %clang_cc1 %s -D__TIME__=1234 -U__DATE__ -E 2>&1 | FileCheck %s --check-prefix=CHECK-OUT
+// RUN: %clang_cc1 %s -D__TIME__=1234 -U__DATE__ -E 2>&1 | FileCheck %s --check-prefix=CHECK-WARN
+// RUN: %clang_cc1 %s -D__TIME__=1234 -U__DATE__ -E 2>&1 -pedantic-errors | FileCheck %s --check-prefix=CHECK-ERR
+
+// CHECK-WARN: <command line>:{{.*}} warning: redefining builtin macro
+// CHECK-WARN: <command line>:{{.*}} warning: undefining builtin macro
+
+// CHECK-ERR: <command line>:{{.*}} error: redefining builtin macro
+// CHECK-ERR: <command line>:{{.*}} error: undefining builtin macro
+
+int n = __TIME__;
+__DATE__
+
+#define __FILE__ "my file"
+// CHECK-WARN: :[[@LINE-1]]:9: warning: redefining builtin macro
+// CHECK-ERR: :[[@LINE-2]]:9: error: redefining builtin macro
+
+// CHECK-OUT: int n = 1234;
+// CHECK-OUT: __DATE__
The list of warnings below should NEVER grow. It should gradually shrink to 0.
-CHECK: Warnings without flags (145):
+CHECK: Warnings without flags (144):
CHECK-NEXT: ext_delete_void_ptr_operand
CHECK-NEXT: ext_enum_friend
CHECK-NEXT: ext_expected_semi_decl_list
CHECK-NEXT: pp_poisoning_existing_macro
CHECK-NEXT: pp_pragma_once_in_main_file
CHECK-NEXT: pp_pragma_sysheader_in_main_file
-CHECK-NEXT: pp_undef_builtin_macro
CHECK-NEXT: w_asm_qualifier_ignored
CHECK-NEXT: warn_accessor_property_type_mismatch
CHECK-NEXT: warn_anon_bitfield_width_exceeds_type_size