[cfe-commits] r152287 - in /cfe/trunk: include/clang/Basic/DiagnosticGroups.td include/clang/Basic/DiagnosticLexKinds.td include/clang/Basic/DiagnosticSemaKinds.td lib/Lex/Lexer.cpp lib/Sema/SemaDeclCXX.cpp test/CXX/lex/lex.literal/lex.ext/p1.cpp test/CXX/lex/lex.literal/lex.ext/p10.cpp test/CXX/over/over.oper/over.literal/p8.cpp test/FixIt/fixit-cxx0x.cpp test/FixIt/fixit-cxx11-compat.cpp test/Parser/cxx0x-literal-operators.cpp test/SemaCXX/cxx0x-compat.cpp

Richard Smith richard-llvm at metafoo.co.uk
Wed Mar 7 18:39:21 PST 2012


Author: rsmith
Date: Wed Mar  7 20:39:21 2012
New Revision: 152287

URL: http://llvm.org/viewvc/llvm-project?rev=152287&view=rev
Log:
Implement C++11 [lex.ext]p10 for string and character literals: a ud-suffix not
starting with an underscore is ill-formed.

Since this rule rejects programs that were using <inttypes.h>'s macros, recover
from this error by treating the ud-suffix as a separate preprocessing-token,
with a DefaultError ExtWarn. The approach of treating such cases as two tokens
is under discussion for standardization, but is in any case a conforming
extension and allows existing codebases to keep building while the committee
makes up its mind.

Reword the warning on the definition of literal operators not starting with
underscores (which are, strangely, legal) to more explicitly state that such
operators can't be called by literals. Remove the special-case diagnostic for
hexfloats, since it was both triggering in the wrong cases and incorrect.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Lex/Lexer.cpp
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp
    cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p10.cpp
    cfe/trunk/test/CXX/over/over.oper/over.literal/p8.cpp
    cfe/trunk/test/FixIt/fixit-cxx0x.cpp
    cfe/trunk/test/FixIt/fixit-cxx11-compat.cpp
    cfe/trunk/test/Parser/cxx0x-literal-operators.cpp
    cfe/trunk/test/SemaCXX/cxx0x-compat.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Wed Mar  7 20:39:21 2012
@@ -79,7 +79,15 @@
 // Name of this warning in GCC
 def : DiagGroup<"narrowing", [CXX11Narrowing]>;
 
-def CXX11Compat : DiagGroup<"c++11-compat", [CXX11Narrowing]>;
+def CXX11CompatReservedUserDefinedLiteral :
+  DiagGroup<"c++11-compat-reserved-user-defined-literal">;
+def ReservedUserDefinedLiteral :
+  DiagGroup<"reserved-user-defined-literal",
+            [CXX11CompatReservedUserDefinedLiteral]>;
+
+def CXX11Compat : DiagGroup<"c++11-compat",
+                            [CXX11Narrowing,
+                             CXX11CompatReservedUserDefinedLiteral]>;
 def : DiagGroup<"c++0x-compat", [CXX11Compat]>;
 
 def : DiagGroup<"effc++">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticLexKinds.td Wed Mar  7 20:39:21 2012
@@ -134,6 +134,13 @@
 def warn_cxx11_compat_user_defined_literal : Warning<
   "identifier after literal will be treated as a user-defined literal suffix "
   "in C++11">, InGroup<CXX11Compat>, DefaultIgnore;
+def warn_cxx11_compat_reserved_user_defined_literal : Warning<
+  "identifier after literal will be treated as a reserved user-defined literal "
+  "suffix in C++11">,
+  InGroup<CXX11CompatReservedUserDefinedLiteral>, DefaultIgnore;
+def ext_reserved_user_defined_literal : ExtWarn<
+  "invalid suffix on literal; C++11 requires a space between literal and "
+  "identifier">, InGroup<ReservedUserDefinedLiteral>, DefaultError;
 def err_unsupported_string_concat : Error<
   "unsupported non-standard concatenation of string literals">;
 def err_string_concat_mixed_suffix : Error<

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Mar  7 20:39:21 2012
@@ -4757,13 +4757,11 @@
   "parameter declaration for literal operator %0 is not valid">;
 def err_literal_operator_extern_c : Error<
   "literal operator must have C++ linkage">;
-def warn_user_literal_hexfloat : Warning<
-  "user-defined literal with suffix '%0' is preempted by C99 hexfloat "
-  "extension">, InGroup<UserDefinedLiterals>;
 def warn_user_literal_reserved : Warning<
-  "user-defined literals not starting with '_' are reserved by the "
-  "implementation">, InGroup<UserDefinedLiterals>;
-  
+  "user-defined literal suffixes not starting with '_' are reserved; "
+  "no literal will invoke this operator">,
+  InGroup<UserDefinedLiterals>;
+
 // C++ conversion functions
 def err_conv_function_not_member : Error<
   "conversion function must be a non-static member function">;

Modified: cfe/trunk/lib/Lex/Lexer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/Lexer.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/lib/Lex/Lexer.cpp (original)
+++ cfe/trunk/lib/Lex/Lexer.cpp Wed Mar  7 20:39:21 2012
@@ -1584,7 +1584,20 @@
   if (isIdentifierHead(C)) {
     if (!getFeatures().CPlusPlus0x) {
       if (!isLexingRawMode())
-        Diag(CurPtr, diag::warn_cxx11_compat_user_defined_literal)
+        Diag(CurPtr,
+             C == '_' ? diag::warn_cxx11_compat_user_defined_literal
+                      : diag::warn_cxx11_compat_reserved_user_defined_literal)
+          << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
+      return CurPtr;
+    }
+
+    // C++11 [lex.ext]p10, [usrlit.suffix]p1: A program containing a ud-suffix
+    // that does not start with an underscore is ill-formed. As a conforming
+    // extension, we treat all such suffixes as if they had whitespace before
+    // them.
+    if (C != '_') {
+      if (!isLexingRawMode())
+        Diag(CurPtr, diag::ext_reserved_user_defined_literal)
           << FixItHint::CreateInsertion(getSourceLocation(CurPtr), " ");
       return CurPtr;
     }

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Mar  7 20:39:21 2012
@@ -9383,30 +9383,15 @@
     return true;
   }
 
-  StringRef LiteralName 
+  StringRef LiteralName
     = FnDecl->getDeclName().getCXXLiteralIdentifier()->getName();
   if (LiteralName[0] != '_') {
-    // C++0x [usrlit.suffix]p1:
-    //   Literal suffix identifiers that do not start with an underscore are 
-    //   reserved for future standardization.
-    bool IsHexFloat = true;
-    if (LiteralName.size() > 1 && 
-        (LiteralName[0] == 'P' || LiteralName[0] == 'p')) {
-      for (unsigned I = 1, N = LiteralName.size(); I < N; ++I) {
-        if (!isdigit(LiteralName[I])) {
-          IsHexFloat = false;
-          break;
-        }
-      }
-    }
-    
-    if (IsHexFloat)
-      Diag(FnDecl->getLocation(), diag::warn_user_literal_hexfloat)
-        << LiteralName;
-    else
-      Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved);
+    // C++11 [usrlit.suffix]p1:
+    //   Literal suffix identifiers that do not start with an underscore
+    //   are reserved for future standardization.
+    Diag(FnDecl->getLocation(), diag::warn_user_literal_reserved);
   }
-  
+
   return false;
 }
 

Modified: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp (original)
+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p1.cpp Wed Mar  7 20:39:21 2012
@@ -1,7 +1,7 @@
 // RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
 
-void operator "" p31(long double); // expected-warning{{user-defined literal with suffix 'p31' is preempted by C99 hexfloat extension}}
+void operator "" p31(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
 void operator "" _p31(long double);
-long double operator "" pi(long double); // expected-warning{{user-defined literals not starting with '_' are reserved by the implementation}}
+long double operator "" pi(long double); // expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
 
 float hexfloat = 0x1p31; // allow hexfloats

Modified: cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p10.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p10.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p10.cpp (original)
+++ cfe/trunk/test/CXX/lex/lex.literal/lex.ext/p10.cpp Wed Mar  7 20:39:21 2012
@@ -1,8 +1,8 @@
 // RUN: %clang_cc1 -std=c++11 -verify %s
 
 using size_t = decltype(sizeof(int));
-void operator "" wibble(const char *); // expected-warning {{preempted}}
-void operator "" wibble(const char *, size_t); // expected-warning {{preempted}}
+void operator "" wibble(const char *); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
+void operator "" wibble(const char *, size_t); // expected-warning {{user-defined literal suffixes not starting with '_' are reserved; no literal will invoke this operator}}
 
 template<typename T>
 void f() {
@@ -10,6 +10,6 @@
   // FIXME: Reject these for the right reason.
   123wibble; // expected-error {{suffix 'wibble'}}
   123.0wibble; // expected-error {{suffix 'wibble'}}
-  ""wibble;
-  R"x("hello")x"wibble;
+  const char *p = ""wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}}
+  const char *q = R"x("hello")x"wibble; // expected-error {{invalid suffix on literal; C++11 requires a space between literal and identifier}} expected-error {{expected ';'}}
 }

Modified: cfe/trunk/test/CXX/over/over.oper/over.literal/p8.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/over/over.oper/over.literal/p8.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/CXX/over/over.oper/over.literal/p8.cpp (original)
+++ cfe/trunk/test/CXX/over/over.oper/over.literal/p8.cpp Wed Mar  7 20:39:21 2012
@@ -9,9 +9,11 @@
 string operator "" _i18n(const char*, std::size_t); // ok
 // FIXME: This should be accepted once we support UCNs
 template<char...> int operator "" \u03C0(); // ok, UCN for lowercase pi // expected-error {{expected identifier}}
-// FIXME: Accept this as an extension, with a fix-it to add the space
-float operator ""E(const char *); // expected-error {{C++11 requires a space between the "" and the user-defined suffix in a literal operator}}
-float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{hexfloat}}
+float operator ""E(const char *); // expected-error {{C++11 requires a space between literal and identifier}} expected-warning {{reserved}}
+float operator " " B(const char *); // expected-error {{must be '""'}} expected-warning {{reserved}}
 string operator "" 5X(const char *, std::size_t); // expected-error {{expected identifier}}
 double operator "" _miles(double); // expected-error {{parameter}}
 template<char...> int operator "" j(const char*); // expected-error {{parameter}}
+
+// FIXME: Accept this as an extension, with a fix-it to add the space
+float operator ""_E(const char *); // expected-error {{C++11 requires a space between the "" and the user-defined suffix in a literal operator}}

Modified: cfe/trunk/test/FixIt/fixit-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx0x.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx0x.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx0x.cpp Wed Mar  7 20:39:21 2012
@@ -60,3 +60,8 @@
   (void)[] mutable { }; // expected-error{{lambda requires '()' before 'mutable'}}
   (void)[] -> int { }; // expected-error{{lambda requires '()' before return type}}
 }
+
+#define bar "bar"
+const char *p = "foo"bar; // expected-error {{requires a space between}}
+#define ord - '0'
+int k = '4'ord; // expected-error {{requires a space between}}

Modified: cfe/trunk/test/FixIt/fixit-cxx11-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/FixIt/fixit-cxx11-compat.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/FixIt/fixit-cxx11-compat.cpp (original)
+++ cfe/trunk/test/FixIt/fixit-cxx11-compat.cpp Wed Mar  7 20:39:21 2012
@@ -6,4 +6,6 @@
 // This is a test of the code modification hints for C++11-compatibility problems.
 
 #define bar "bar"
-const char *p = "foo"bar; // expected-warning {{will be treated as a user-defined literal suffix}}
+const char *p = "foo"bar; // expected-warning {{will be treated as a reserved user-defined literal suffix}}
+#define _bar "_bar"
+const char *q = "foo"_bar; // expected-warning {{will be treated as a user-defined literal suffix}}

Modified: cfe/trunk/test/Parser/cxx0x-literal-operators.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Parser/cxx0x-literal-operators.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/Parser/cxx0x-literal-operators.cpp (original)
+++ cfe/trunk/test/Parser/cxx0x-literal-operators.cpp Wed Mar  7 20:39:21 2012
@@ -1,6 +1,8 @@
 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
 
 void operator "" (const char *); // expected-error {{expected identifier}}
-void operator "k" foo(const char *); // expected-error {{string literal after 'operator' must be '""'}} \
-// expected-warning{{user-defined literal with suffix 'foo' is preempted by C99 hexfloat extension}}
-void operator "" tester (const char *); // expected-warning{{user-defined literal with suffix 'tester' is preempted by C99 hexfloat extension}}
+void operator "k" foo(const char *); // \
+  expected-error {{string literal after 'operator' must be '""'}} \
+  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}
+void operator "" tester (const char *); // \
+  expected-warning{{user-defined literal suffixes not starting with '_' are reserved}}

Modified: cfe/trunk/test/SemaCXX/cxx0x-compat.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/cxx0x-compat.cpp?rev=152287&r1=152286&r2=152287&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/cxx0x-compat.cpp (original)
+++ cfe/trunk/test/SemaCXX/cxx0x-compat.cpp Wed Mar  7 20:39:21 2012
@@ -32,8 +32,8 @@
 int printf(const char *, ...);
 typedef __typeof(sizeof(int)) size_t;
 void h(size_t foo, size_t bar) {
-  printf("foo is %"PRIuS", bar is %"PRIuS, foo, bar); // expected-warning 2{{identifier after literal will be treated as a user-defined literal suffix in C++11}}
+  printf("foo is %"PRIuS", bar is %"PRIuS, foo, bar); // expected-warning 2{{identifier after literal will be treated as a reserved user-defined literal suffix in C++11}}
 }
 
-#define x + 1
-char c = 'x'x; // expected-warning {{will be treated as a user-defined literal suffix}}
+#define _x + 1
+char c = 'x'_x; // expected-warning {{will be treated as a user-defined literal suffix}}





More information about the cfe-commits mailing list