aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticGroups.td1
-rw-r--r--include/clang/Basic/DiagnosticLexKinds.td7
-rw-r--r--lib/Lex/PPDirectives.cpp21
-rw-r--r--test/Lexer/builtin_redef.c19
-rw-r--r--test/Misc/warning-flags.c3
5 files changed, 37 insertions, 14 deletions
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 69af407342..7b921953ff 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -39,6 +39,7 @@ def NullConversion : DiagGroup<"null-conversion">;
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">;
diff --git a/include/clang/Basic/DiagnosticLexKinds.td b/include/clang/Basic/DiagnosticLexKinds.td
index 7281d07a3b..f693257ec9 100644
--- a/include/clang/Basic/DiagnosticLexKinds.td
+++ b/include/clang/Basic/DiagnosticLexKinds.td
@@ -253,9 +253,10 @@ def pp_pragma_sysheader_in_main_file : Warning<
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">>;
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 07f24c8200..8379ca8719 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -143,15 +143,14 @@ void Preprocessor::ReadMacroName(Token &MacroNameTok, char isDefineUndef) {
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;
@@ -1925,10 +1924,14 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) {
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);
diff --git a/test/Lexer/builtin_redef.c b/test/Lexer/builtin_redef.c
new file mode 100644
index 0000000000..c9351dc4a6
--- /dev/null
+++ b/test/Lexer/builtin_redef.c
@@ -0,0 +1,19 @@
+// 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__
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index 265e178fa7..931de8365b 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -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 (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
@@ -44,7 +44,6 @@ CHECK-NEXT: pp_out_of_date_dependency
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