]> granicus.if.org Git - clang/commitdiff
Update new expression to make use of Declarator::getSourceRange().
authorSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 9 Feb 2009 18:24:27 +0000 (18:24 +0000)
committerSebastian Redl <sebastian.redl@getdesigned.at>
Mon, 9 Feb 2009 18:24:27 +0000 (18:24 +0000)
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
lib/Sema/Sema.h
lib/Sema/SemaExprCXX.cpp
test/SemaCXX/new-delete.cpp

index 199ad29ec60057d8ffaad25ffebf837e7e343665..106d0eb453ff0cc3353e52e1a717b7541c582597 100644 (file)
@@ -96,7 +96,7 @@ bool Type::isVoidType() const {
 }
 
 bool Type::isObjectType() const {
-  if (isa<FunctionType>(CanonicalType))
+  if (isa<FunctionType>(CanonicalType) || isa<ReferenceType>(CanonicalType))
     return false;
   if (const ASQualType *AS = dyn_cast<ASQualType>(CanonicalType))
     return AS->getBaseType()->isObjectType();
index 6175e9275896da97abe27e50c16f69961db7ad98..f0544eb50eb3f48051a90d6ae2cf9f4f04f222c5 100644 (file)
@@ -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,
index 9155ec45d7669c160ad1711f65630da54bc1c66d..4bfd4fa0b569bf17684896a964afebe8616b5815 100644 (file)
@@ -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<Expr*>(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<CXXRecordType>(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;
   }
index 5618b47f2089af4efe60117f30957040d686af4f..76112641affcbbfbf0777729eb737766fcf852cf 100644 (file)
@@ -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.
 }