From: Chris Lattner Date: Sat, 25 Apr 2009 08:35:12 +0000 (+0000) Subject: change a couple more c++ sema methods to be based on isinvalid bits. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6e4750188e836e119f8605cbd34023d0a3b18011;p=clang change a couple more c++ sema methods to be based on isinvalid bits. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70022 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 710f630219..e30f1287a1 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1684,10 +1684,10 @@ public: QualType CheckConstructorDeclarator(Declarator &D, QualType R, FunctionDecl::StorageClass& SC); - bool CheckConstructor(CXXConstructorDecl *Constructor); + void CheckConstructor(CXXConstructorDecl *Constructor); QualType CheckDestructorDeclarator(Declarator &D, FunctionDecl::StorageClass& SC); - bool CheckConversionDeclarator(Declarator &D, QualType &R, + void CheckConversionDeclarator(Declarator &D, QualType &R, FunctionDecl::StorageClass& SC); DeclPtrTy ActOnConversionDeclarator(CXXConversionDecl *Conversion); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 9710bd95df..fd6cf525b9 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2030,16 +2030,14 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member); return 0; - } else { - if (!D.isInvalidType()) - D.setInvalidType(CheckConversionDeclarator(D, R, SC)); - - NewFD = CXXConversionDecl::Create(Context, cast(DC), - D.getIdentifierLoc(), Name, R, - isInline, isExplicit); - - isVirtualOkay = true; } + + CheckConversionDeclarator(D, R, SC); + NewFD = CXXConversionDecl::Create(Context, cast(DC), + D.getIdentifierLoc(), Name, R, + isInline, isExplicit); + + isVirtualOkay = true; } else if (DC->isRecord()) { // This is a C++ method declaration. NewFD = CXXMethodDecl::Create(Context, cast(DC), @@ -2315,8 +2313,7 @@ void Sema::CheckFunctionDeclaration(FunctionDecl *NewFD, NamedDecl *&PrevDecl, if (getLangOptions().CPlusPlus) { // C++-specific checks. if (CXXConstructorDecl *Constructor = dyn_cast(NewFD)) { - if (CheckConstructor(Constructor)) - return NewFD->setInvalidDecl(); + CheckConstructor(Constructor); } else if (isa(NewFD)) { CXXRecordDecl *Record = cast(NewFD->getParent()); Record->setUserDeclaredDestructor(true); diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index 74e91a9bb4..bc87c6775a 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -1253,10 +1253,8 @@ void Sema::ActOnFinishDelayedCXXMethodDeclaration(Scope *S, DeclPtrTy MethodD) { // again. It could produce additional diagnostics or affect whether // the class has implicitly-declared destructors, among other // things. - if (CXXConstructorDecl *Constructor = dyn_cast(Method)) { - if (CheckConstructor(Constructor)) - Constructor->setInvalidDecl(); - } + if (CXXConstructorDecl *Constructor = dyn_cast(Method)) + CheckConstructor(Constructor); // Check the default arguments, which we may have added. if (!Method->isInvalidDecl()) @@ -1334,13 +1332,11 @@ QualType Sema::CheckConstructorDeclarator(Declarator &D, QualType R, /// CheckConstructor - Checks a fully-formed constructor for /// well-formedness, issuing any diagnostics required. Returns true if /// the constructor declarator is invalid. -bool Sema::CheckConstructor(CXXConstructorDecl *Constructor) { +void Sema::CheckConstructor(CXXConstructorDecl *Constructor) { CXXRecordDecl *ClassDecl = dyn_cast(Constructor->getDeclContext()); if (!ClassDecl) - return true; - - bool Invalid = Constructor->isInvalidDecl(); + return Constructor->setInvalidDecl(); // C++ [class.copy]p3: // A declaration of a constructor for a class X is ill-formed if @@ -1357,14 +1353,12 @@ bool Sema::CheckConstructor(CXXConstructorDecl *Constructor) { SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation(); Diag(ParamLoc, diag::err_constructor_byvalue_arg) << CodeModificationHint::CreateInsertion(ParamLoc, " const &"); - Invalid = true; + Constructor->setInvalidDecl(); } } // Notify the class that we've added a constructor. ClassDecl->addedConstructor(Context, Constructor); - - return Invalid; } /// CheckDestructorDeclarator - Called by ActOnDeclarator to check @@ -1460,22 +1454,21 @@ QualType Sema::CheckDestructorDeclarator(Declarator &D, /// will emit diagnostics and return true. Otherwise, it will return /// false. Either way, the type @p R will be updated to reflect a /// well-formed type for the conversion operator. -bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R, +void Sema::CheckConversionDeclarator(Declarator &D, QualType &R, FunctionDecl::StorageClass& SC) { - bool isInvalid = false; - // C++ [class.conv.fct]p1: // Neither parameter types nor return type can be specified. The // type of a conversion function (8.3.5) is “function taking no // parameter returning conversion-type-id.” if (SC == FunctionDecl::Static) { - Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member) - << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) - << SourceRange(D.getIdentifierLoc()); - isInvalid = true; + if (!D.isInvalidType()) + Diag(D.getIdentifierLoc(), diag::err_conv_function_not_member) + << "static" << SourceRange(D.getDeclSpec().getStorageClassSpecLoc()) + << SourceRange(D.getIdentifierLoc()); + D.setInvalidType(); SC = FunctionDecl::None; } - if (D.getDeclSpec().hasTypeSpecifier()) { + if (D.getDeclSpec().hasTypeSpecifier() && !D.isInvalidType()) { // Conversion functions don't have return types, but the parser will // happily parse something like: // @@ -1495,11 +1488,14 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R, // Delete the parameters. D.getTypeObject(0).Fun.freeArgs(); + D.setInvalidType(); } // Make sure the conversion function isn't variadic. - if (R->getAsFunctionProtoType()->isVariadic()) + if (R->getAsFunctionProtoType()->isVariadic() && !D.isInvalidType()) { Diag(D.getIdentifierLoc(), diag::err_conv_function_variadic); + D.setInvalidType(); + } // C++ [class.conv.fct]p4: // The conversion-type-id shall not represent a function type nor @@ -1508,9 +1504,11 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R, if (ConvType->isArrayType()) { Diag(D.getIdentifierLoc(), diag::err_conv_function_to_array); ConvType = Context.getPointerType(ConvType); + D.setInvalidType(); } else if (ConvType->isFunctionType()) { Diag(D.getIdentifierLoc(), diag::err_conv_function_to_function); ConvType = Context.getPointerType(ConvType); + D.setInvalidType(); } // Rebuild the function type "R" without any parameters (in case any @@ -1524,8 +1522,6 @@ bool Sema::CheckConversionDeclarator(Declarator &D, QualType &R, Diag(D.getDeclSpec().getExplicitSpecLoc(), diag::warn_explicit_conversion_functions) << SourceRange(D.getDeclSpec().getExplicitSpecLoc()); - - return isInvalid; } /// ActOnConversionDeclarator - Called by ActOnDeclarator to complete diff --git a/test/SemaCXX/conversion-function.cpp b/test/SemaCXX/conversion-function.cpp index 1ecea89aab..1ca1e689ea 100644 --- a/test/SemaCXX/conversion-function.cpp +++ b/test/SemaCXX/conversion-function.cpp @@ -23,8 +23,11 @@ typedef int array_type[10]; class Y { public: void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \ - // expected-error{{conversion function cannot have any parameters}} \ - // expected-error{{conversion function cannot be variadic}} + // expected-error{{conversion function cannot have any parameters}} + + operator float(...) const; // expected-error{{conversion function cannot be variadic}} + + operator func_type(); // expected-error{{conversion function cannot convert to a function type}} operator array_type(); // expected-error{{conversion function cannot convert to an array type}} };