]> granicus.if.org Git - clang/commitdiff
PR23942: a pure-specifier's integer literal must be spelled '0'
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 29 Jun 2015 23:19:23 +0000 (23:19 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 29 Jun 2015 23:19:23 +0000 (23:19 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@241019 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
test/Parser/cxx-class.cpp

index ae97b24f853a7b7bd9e8bbaed9dc42619dec97d3..bce0a3744603dcbee3aba801173d68107ec5aaec 100644 (file)
@@ -8783,6 +8783,19 @@ namespace {
   }
 }
 
+/// Determine whether the given expression was formed from the token '0'. This
+/// test is necessary to determine whether an initializer is really a
+/// pure-specifier.
+static bool isZeroToken(Sema &S, Expr *E) {
+  auto *IL = dyn_cast<IntegerLiteral>(E);
+  if (!IL || !!IL->getValue() ||
+      !IL->getType()->isSpecificBuiltinType(BuiltinType::Int))
+    return false;
+
+  SmallString<8> Buffer;
+  return S.PP.getSpelling(E->getLocStart(), Buffer) == "0";
+}
+
 /// AddInitializerToDecl - Adds the initializer Init to the
 /// declaration dcl. If DirectInit is true, this is C++ direct
 /// initialization rather than copy initialization.
@@ -8799,9 +8812,11 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init,
     // With declarators parsed the way they are, the parser cannot
     // distinguish between a normal initializer and a pure-specifier.
     // Thus this grotesque test.
-    IntegerLiteral *IL;
-    if ((IL = dyn_cast<IntegerLiteral>(Init)) && IL->getValue() == 0 &&
-        Context.getCanonicalType(IL->getType()) == Context.IntTy)
+    //
+    // FIXME: The parser should instead treat anything that looks like a
+    // pure-specifier as a pure-specifier, and Sema should convert it to an
+    // initializer when necessary, rather than doing things this way around.
+    if (!DirectInit && isZeroToken(*this, Init))
       CheckPureMethod(Method, Init->getSourceRange());
     else {
       Diag(Method->getLocation(), diag::err_member_function_initialization)
index 38eef1756d0f23291e251e02624d74bf891829fd..9e907f1b1c12f8faa34d704bfaf4a92715d8afca 100644 (file)
@@ -24,6 +24,16 @@ public:
   ; // expected-warning{{extra ';' inside a class}}
 
   virtual int vf() const volatile = 0;
+
+  virtual int vf0() = 0l; // expected-error {{does not look like a pure-specifier}}
+  virtual int vf1() = 1; // expected-error {{does not look like a pure-specifier}}
+  virtual int vf2() = 00; // expected-error {{does not look like a pure-specifier}}
+  virtual int vf3() = 0x0; // expected-error {{does not look like a pure-specifier}}
+  virtual int vf4() = 0.0; // expected-error {{does not look like a pure-specifier}}
+  virtual int vf5(){0}; // expected-error +{{}} expected-warning {{unused}}
+  virtual int vf5a(){0;}; // function definition, expected-warning {{unused}}
+  virtual int vf6()(0); // expected-error +{{}} expected-note +{{}}
+  virtual int vf7() = { 0 }; // expected-error {{does not look like a pure-specifier}}
   
 private:
   int x,f(),y,g();