diff options
author | John McCall <rjmccall@apple.com> | 2010-04-13 00:04:31 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-04-13 00:04:31 +0000 |
commit | a3f8137d9f7cd1af7a6cbe736b9419f7eb99e86c (patch) | |
tree | 3538911a019548d669fa76c0f10ef3bf3a77d737 /lib/Sema/SemaDeclCXX.cpp | |
parent | 88aae9188a64fe6385c7057af068aaeb8fc96b8e (diff) |
Diagnose declarations of conversion functions with declarators other than '()'.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@101098 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index d832978054..b1aa2e879a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2828,6 +2828,9 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, D.setInvalidType(); SC = FunctionDecl::None; } + + QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId); + if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { // Conversion functions don't have return types, but the parser will // happily parse something like: @@ -2840,27 +2843,35 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, Diag(D.getIdentifierLoc(), diag::err_conv_function_return_type) << SourceRange(D.getDeclSpec().getTypeSpecTypeLoc()) << SourceRange(D.getIdentifierLoc()); + D.setInvalidType(); } + const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); + // Make sure we don't have any parameters. - if (R->getAs<FunctionProtoType>()->getNumArgs() > 0) { + if (Proto->getNumArgs() > 0) { Diag(D.getIdentifierLoc(), diag::err_conv_function_with_params); // Delete the parameters. D.getTypeObject(0).Fun.freeArgs(); D.setInvalidType(); + } else if (Proto->isVariadic()) { + Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic); + D.setInvalidType(); } - // Make sure the conversion function isn't variadic. - if (R->getAs<FunctionProtoType>()->isVariadic() && !D.isInvalidType()) { - Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic); + // Diagnose "&operator bool()" and other such nonsense. This + // is actually a gcc extension which we don't support. + if (Proto->getResultType() != ConvType) { + Diag(D.getIdentifierLoc(), diag::err_conv_function_with_complex_decl) + << Proto->getResultType(); D.setInvalidType(); + ConvType = Proto->getResultType(); } // C++ [class.conv.fct]p4: // The conversion-type-id shall not represent a function type nor // an array type. - QualType ConvType = GetTypeFromParser(D.getName().ConversionFunctionId); if (ConvType->isArrayType()) { Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array); ConvType = Context.getPointerType(ConvType); @@ -2874,14 +2885,15 @@ void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, // Rebuild the function type "R" without any parameters (in case any // of the errors above fired) and with the conversion type as the // return type. - const FunctionProtoType *Proto = R->getAs<FunctionProtoType>(); - R = Context.getFunctionType(ConvType, 0, 0, false, - Proto->getTypeQuals(), - Proto->hasExceptionSpec(), - Proto->hasAnyExceptionSpec(), - Proto->getNumExceptions(), - Proto->exception_begin(), - Proto->getExtInfo()); + if (D.isInvalidType()) { + R = Context.getFunctionType(ConvType, 0, 0, false, + Proto->getTypeQuals(), + Proto->hasExceptionSpec(), + Proto->hasAnyExceptionSpec(), + Proto->getNumExceptions(), + Proto->exception_begin(), + Proto->getExtInfo()); + } // C++0x explicit conversion operators. if (D.getDeclSpec().isExplicitSpecified() && !getLangOptions().CPlusPlus0x) |