[clang] 9b222b1 - [c++20] Don't consider string literal operator templates for numeric

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Mon Jan 11 13:19:11 PST 2021


Author: Richard Smith
Date: 2021-01-11T13:19:00-08:00
New Revision: 9b222b108a2e37eb45d3156ec8554d148d658a8a

URL: https://github.com/llvm/llvm-project/commit/9b222b108a2e37eb45d3156ec8554d148d658a8a
DIFF: https://github.com/llvm/llvm-project/commit/9b222b108a2e37eb45d3156ec8554d148d658a8a.diff

LOG: [c++20] Don't consider string literal operator templates for numeric
literals.

A literal interpretation of the standard wording allows this, but it was
never intended that string literal operator templates would be used for
anything other than user-defined string literals.

Added: 
    

Modified: 
    clang/lib/Sema/SemaLookup.cpp
    clang/test/SemaCXX/cxx2a-user-defined-literals.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 16dd8f5105961..29038ab9fe1ca 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -3384,6 +3384,13 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
       TemplateParameterList *Params = FD->getTemplateParameters();
       if (Params->size() == 1) {
         IsTemplate = true;
+        if (!Params->getParam(0)->isTemplateParameterPack() && !StringLit) {
+          // Implied but not stated: user-defined integer and floating literals
+          // only ever use numeric literal operator templates, not templates
+          // taking a parameter of class type.
+          F.erase();
+          continue;
+        }
 
         // A string literal template is only considered if the string literal
         // is a well-formed template argument for the template parameter.

diff  --git a/clang/test/SemaCXX/cxx2a-user-defined-literals.cpp b/clang/test/SemaCXX/cxx2a-user-defined-literals.cpp
index d730eba741a88..12f672ff640a9 100644
--- a/clang/test/SemaCXX/cxx2a-user-defined-literals.cpp
+++ b/clang/test/SemaCXX/cxx2a-user-defined-literals.cpp
@@ -24,4 +24,33 @@ chrono::day bin_d = 0b011d;
 // expected-note at 9{{candidate constructor (the implicit move constructor)}}
 chrono::day hex_d = 0x44d;
 chrono::year y  = 10y;
+
+namespace ignore_class_udl_for_numeric_literals {
+  struct A { constexpr A(const char*) {} };
+  struct B { constexpr B(char); };
+  struct C { constexpr C(int); };
+  template<A> void operator""_a();
+  template<B> void operator""_b();
+  template<C> void operator""_c();
+  void test_class_udl_1() {
+    1_a; // expected-error {{no matching}}
+    1_b; // expected-error {{no matching}}
+    1_c; // expected-error {{no matching}}
+    "1"_a;
+    "1"_b; // expected-error {{no matching}}
+    "1"_c; // expected-error {{no matching}}
+  }
+  template<char...> void operator""_a();
+  template<char...> void operator""_b();
+  template<char...> void operator""_c();
+  void test_class_udl_2() {
+    1_a;
+    // FIXME: The standard appears to say these two are ambiguous!
+    1_b;
+    1_c;
+    "1"_a;
+    "1"_b; // expected-error {{no matching}}
+    "1"_c; // expected-error {{no matching}}
+  }
+}
 #endif


        


More information about the cfe-commits mailing list