From 00e68e2cc5ce37cb95beb801cae73c0d1e9dda37 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 9 Feb 2009 18:24:27 +0000 Subject: [PATCH] Update new expression to make use of Declarator::getSourceRange(). References are not objects; implement this in Type::isObjectType(). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64152 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/Type.cpp | 2 +- lib/Sema/Sema.h | 9 +++--- lib/Sema/SemaExprCXX.cpp | 60 +++++++++++++++++-------------------- test/SemaCXX/new-delete.cpp | 3 ++ 4 files changed, 36 insertions(+), 38 deletions(-) diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 199ad29ec6..106d0eb453 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -96,7 +96,7 @@ bool Type::isVoidType() const { } bool Type::isObjectType() const { - if (isa(CanonicalType)) + if (isa(CanonicalType) || isa(CanonicalType)) return false; if (const ASQualType *AS = dyn_cast(CanonicalType)) return AS->getBaseType()->isObjectType(); diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 6175e92758..f0544eb50e 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -1305,13 +1305,14 @@ public: ExprTy **ConstructorArgs, unsigned NumConsArgs, SourceLocation ConstructorRParen); bool CheckAllocatedType(QualType AllocType, const Declarator &D); - bool FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal, - QualType AllocType, bool IsArray, + bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, + bool UseGlobal, QualType AllocType, bool IsArray, Expr **PlaceArgs, unsigned NumPlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete); - bool FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, - Expr** Args, unsigned NumArgs, DeclContext *Ctx, + bool FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, + DeclarationName Name, Expr** Args, + unsigned NumArgs, DeclContext *Ctx, bool AllowMissing, FunctionDecl *&Operator); void DeclareGlobalNewDelete(); void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index 9155ec45d7..4bfd4fa0b5 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -197,10 +197,6 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, ExprTy **ConstructorArgs, unsigned NumConsArgs, SourceLocation ConstructorRParen) { - // FIXME: Throughout this function, we have rather bad location information. - // Implementing Declarator::getSourceRange() would go a long way toward - // fixing that. - Expr *ArraySize = 0; unsigned Skip = 0; // If the specified type is an array, unwrap it and save the expression. @@ -208,9 +204,11 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, D.getTypeObject(0).Kind == DeclaratorChunk::Array) { DeclaratorChunk &Chunk = D.getTypeObject(0); if (Chunk.Arr.hasStatic) - return Diag(Chunk.Loc, diag::err_static_illegal_in_new); + return Diag(Chunk.Loc, diag::err_static_illegal_in_new) + << D.getSourceRange(); if (!Chunk.Arr.NumElts) - return Diag(Chunk.Loc, diag::err_array_new_needs_size); + return Diag(Chunk.Loc, diag::err_array_new_needs_size) + << D.getSourceRange(); ArraySize = static_cast(Chunk.Arr.NumElts); Skip = 1; } @@ -251,9 +249,10 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, FunctionDecl *OperatorNew = 0; FunctionDecl *OperatorDelete = 0; Expr **PlaceArgs = (Expr**)PlacementArgs; - if (FindAllocationFunctions(StartLoc, UseGlobal, AllocType, ArraySize, - PlaceArgs, NumPlaceArgs, OperatorNew, - OperatorDelete)) + if (FindAllocationFunctions(StartLoc, + SourceRange(PlacementLParen, PlacementRParen), + UseGlobal, AllocType, ArraySize, PlaceArgs, + NumPlaceArgs, OperatorNew, OperatorDelete)) return true; bool Init = ConstructorLParen.isValid(); @@ -276,13 +275,14 @@ Sema::ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, // 2) Otherwise, the object is direct-initialized. CXXConstructorDecl *Constructor = 0; Expr **ConsArgs = (Expr**)ConstructorArgs; + // FIXME: Should check for primitive/aggregate here, not record. if (const RecordType *RT = AllocType->getAsRecordType()) { // FIXME: This is incorrect for when there is an empty initializer and // no user-defined constructor. Must zero-initialize, not default-construct. Constructor = PerformInitializationByConstructor( AllocType, ConsArgs, NumConsArgs, - D.getDeclSpec().getSourceRange().getBegin(), - SourceRange(D.getDeclSpec().getSourceRange().getBegin(), + D.getSourceRange().getBegin(), + SourceRange(D.getSourceRange().getBegin(), ConstructorRParen), RT->getDecl()->getDeclName(), NumConsArgs != 0 ? IK_Direct : IK_Default); @@ -336,15 +336,11 @@ bool Sema::CheckAllocatedType(QualType AllocType, const Declarator &D) } else if(AllocType->isIncompleteType()) { type = 1; } else { - assert(AllocType->isReferenceType() && "What else could it be?"); + assert(AllocType->isReferenceType() && "Unhandled non-object type."); type = 2; } - SourceRange TyR = D.getDeclSpec().getSourceRange(); - // FIXME: This is very much a guess and won't work for, e.g., pointers. - if (D.getNumTypeObjects() > 0) - TyR.setEnd(D.getTypeObject(0).Loc); - Diag(TyR.getBegin(), diag::err_bad_new_type) - << AllocType.getAsString() << type << TyR; + Diag(D.getSourceRange().getBegin(), diag::err_bad_new_type) + << AllocType << type << D.getSourceRange(); return true; } @@ -365,9 +361,10 @@ bool Sema::CheckAllocatedType(QualType AllocType, const Declarator &D) /// FindAllocationFunctions - Finds the overloads of operator new and delete /// that are appropriate for the allocation. -bool Sema::FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal, - QualType AllocType, bool IsArray, - Expr **PlaceArgs, unsigned NumPlaceArgs, +bool Sema::FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, + bool UseGlobal, QualType AllocType, + bool IsArray, Expr **PlaceArgs, + unsigned NumPlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete) { @@ -397,7 +394,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal, CXXRecordDecl *Record = cast(AllocType->getAsRecordType()) ->getDecl(); // FIXME: We fail to find inherited overloads. - if (FindAllocationOverload(StartLoc, NewName, &AllocArgs[0], + if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0], AllocArgs.size(), Record, /*AllowMissing=*/true, OperatorNew)) return true; @@ -406,7 +403,7 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal, // Didn't find a member overload. Look for a global one. DeclareGlobalNewDelete(); DeclContext *TUDecl = Context.getTranslationUnitDecl(); - if (FindAllocationOverload(StartLoc, NewName, &AllocArgs[0], + if (FindAllocationOverload(StartLoc, Range, NewName, &AllocArgs[0], AllocArgs.size(), TUDecl, /*AllowMissing=*/false, OperatorNew)) return true; @@ -420,19 +417,18 @@ bool Sema::FindAllocationFunctions(SourceLocation StartLoc, bool UseGlobal, /// FindAllocationOverload - Find an fitting overload for the allocation /// function in the specified scope. -bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, - Expr** Args, unsigned NumArgs, - DeclContext *Ctx, bool AllowMissing, - FunctionDecl *&Operator) +bool Sema::FindAllocationOverload(SourceLocation StartLoc, SourceRange Range, + DeclarationName Name, Expr** Args, + unsigned NumArgs, DeclContext *Ctx, + bool AllowMissing, FunctionDecl *&Operator) { DeclContext::lookup_iterator Alloc, AllocEnd; llvm::tie(Alloc, AllocEnd) = Ctx->lookup(Name); if (Alloc == AllocEnd) { if (AllowMissing) return false; - // FIXME: Bad location information. return Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) - << Name << 0; + << Name << 0 << Range; } OverloadCandidateSet Candidates; @@ -467,16 +463,14 @@ bool Sema::FindAllocationOverload(SourceLocation StartLoc, DeclarationName Name, case OR_No_Viable_Function: if (AllowMissing) return false; - // FIXME: Bad location information. Diag(StartLoc, diag::err_ovl_no_viable_function_in_call) - << Name << (unsigned)Candidates.size(); + << Name << (unsigned)Candidates.size() << Range; PrintOverloadCandidates(Candidates, /*OnlyViable=*/false); return true; case OR_Ambiguous: - // FIXME: Bad location information. Diag(StartLoc, diag::err_ovl_ambiguous_call) - << Name; + << Name << Range; PrintOverloadCandidates(Candidates, /*OnlyViable=*/true); return true; } diff --git a/test/SemaCXX/new-delete.cpp b/test/SemaCXX/new-delete.cpp index 5618b47f20..76112641af 100644 --- a/test/SemaCXX/new-delete.cpp +++ b/test/SemaCXX/new-delete.cpp @@ -64,6 +64,9 @@ void bad_news(int *ip) (void)new (0L) int; // expected-error {{call to 'operator new' is ambiguous}} // This must fail, because the member version shouldn't be found. (void)::new ((S*)0) U; // expected-error {{no matching function for call to 'operator new'}} + (void)new (int[]); // expected-error {{array size must be specified in new expressions}} + (void)new int&; // expected-error {{cannot allocate reference type 'int &' with new}} + (void)new (void ()); // expected-error {{cannot allocate function type 'void (void)' with new}} // Some lacking cases due to lack of sema support. } -- 2.40.0