r329924 - Correctly diagnose when a conversion function is declared with a type qualifier in the declaration specifiers rather than in the conversion type id. Fixes PR30595.

Aaron Ballman via cfe-commits cfe-commits at lists.llvm.org
Thu Apr 12 09:41:55 PDT 2018


Author: aaronballman
Date: Thu Apr 12 09:41:55 2018
New Revision: 329924

URL: http://llvm.org/viewvc/llvm-project?rev=329924&view=rev
Log:
Correctly diagnose when a conversion function is declared with a type qualifier in the declaration specifiers rather than in the conversion type id. Fixes PR30595.

Modified:
    cfe/trunk/lib/Sema/SemaDeclCXX.cpp
    cfe/trunk/test/SemaCXX/conversion-function.cpp

Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=329924&r1=329923&r2=329924&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Thu Apr 12 09:41:55 2018
@@ -8319,7 +8319,8 @@ void Sema::CheckConversionDeclarator(Dec
   QualType ConvType =
       GetTypeFromParser(D.getName().ConversionFunctionId, &ConvTSI);
 
-  if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) {
+  const DeclSpec &DS = D.getDeclSpec();
+  if (DS.hasTypeSpecifier() && !D.isInvalidType()) {
     // Conversion functions don't have return types, but the parser will
     // happily parse something like:
     //
@@ -8329,9 +8330,18 @@ void Sema::CheckConversionDeclarator(Dec
     //
     // The return type will be changed later anyway.
     Diag(D.getIdentifierLoc(), diag::err_conv_function_return_type)
-      << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc())
+      << SourceRange(DS.getTypeSpecTypeLoc())
       << SourceRange(D.getIdentifierLoc());
     D.setInvalidType();
+  } else if (DS.getTypeQualifiers() && !D.isInvalidType()) {
+    // It's also plausible that the user writes type qualifiers in the wrong
+    // place, such as:
+    //   struct S { const operator int(); };
+    // FIXME: we could provide a fixit to move the qualifiers onto the
+    // conversion type.
+    Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl)
+        << SourceRange(D.getIdentifierLoc()) << 0;
+    D.setInvalidType();
   }
 
   const FunctionProtoType *Proto = R->getAs<FunctionProtoType>();
@@ -8444,12 +8454,12 @@ void Sema::CheckConversionDeclarator(Dec
     R = Context.getFunctionType(ConvType, None, Proto->getExtProtoInfo());
 
   // C++0x explicit conversion operators.
-  if (D.getDeclSpec().isExplicitSpecified())
-    Diag(D.getDeclSpec().getExplicitSpecLoc(),
-         getLangOpts().CPlusPlus11 ?
-           diag::warn_cxx98_compat_explicit_conversion_functions :
-           diag::ext_explicit_conversion_functions)
-      << SourceRange(D.getDeclSpec().getExplicitSpecLoc());
+  if (DS.isExplicitSpecified())
+    Diag(DS.getExplicitSpecLoc(),
+         getLangOpts().CPlusPlus11
+             ? diag::warn_cxx98_compat_explicit_conversion_functions
+             : diag::ext_explicit_conversion_functions)
+        << SourceRange(DS.getExplicitSpecLoc());
 }
 
 /// ActOnConversionDeclarator - Called by ActOnDeclarator to complete

Modified: cfe/trunk/test/SemaCXX/conversion-function.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/conversion-function.cpp?rev=329924&r1=329923&r2=329924&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/conversion-function.cpp (original)
+++ cfe/trunk/test/SemaCXX/conversion-function.cpp Thu Apr 12 09:41:55 2018
@@ -444,3 +444,13 @@ namespace PR18234 {
   bool k1 = e == A::e; // expected-error {{no member named 'e'}}
   bool k2 = e.n == 0;
 }
+
+namespace PR30595 {
+struct S {
+  const operator int(); // expected-error {{cannot specify any part of a return type in the declaration of a conversion function; put the complete type after 'operator'}}
+  const operator int() const; // expected-error {{cannot specify any part of a return type}}
+  volatile const operator int(); // expected-error {{cannot specify any part of a return type}}
+
+  operator const int() const;
+};
+}




More information about the cfe-commits mailing list