[cfe-commits] r150688 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/SemaCXX/new-delete-cxx0x.cpp
Sebastian Redl
sebastian.redl at getdesigned.at
Thu Feb 16 04:59:48 PST 2012
Author: cornedbee
Date: Thu Feb 16 06:59:47 2012
New Revision: 150688
URL: http://llvm.org/viewvc/llvm-project?rev=150688&view=rev
Log:
Proper checking of list-initializers for array new expressions.
This finishes generalized initializer support in Sema.
Modified:
cfe/trunk/lib/Sema/SemaExprCXX.cpp
cfe/trunk/test/SemaCXX/new-delete-cxx0x.cpp
Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=150688&r1=150687&r2=150688&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu Feb 16 06:59:47 2012
@@ -30,6 +30,7 @@
#include "clang/Basic/TargetInfo.h"
#include "clang/Lex/Preprocessor.h"
#include "TypeLocBuilder.h"
+#include "llvm/ADT/APInt.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/ErrorHandling.h"
using namespace clang;
@@ -976,7 +977,8 @@
TypeContainsAuto);
}
-static bool isLegalArrayNewInitializer(Expr *Init) {
+static bool isLegalArrayNewInitializer(CXXNewExpr::InitializationStyle Style,
+ Expr *Init) {
if (!Init)
return true;
if (ParenListExpr *PLE = dyn_cast<ParenListExpr>(Init)) {
@@ -989,6 +991,11 @@
else if (CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init))
return !CCE->isListInitialization() &&
CCE->getConstructor()->isDefaultConstructor();
+ else if (Style == CXXNewExpr::ListInit) {
+ assert(isa<InitListExpr>(Init) &&
+ "Shouldn't create list CXXConstructExprs for arrays.");
+ return true;
+ }
return false;
}
@@ -1240,14 +1247,26 @@
}
}
+ QualType InitType = AllocType;
// Array 'new' can't have any initializers except empty parentheses.
- if (!isLegalArrayNewInitializer(Initializer) &&
- (ResultType->isArrayType() || ArraySize)) {
- SourceRange InitRange(Inits[0]->getLocStart(),
- Inits[NumInits - 1]->getLocEnd());
-
- Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
- return ExprError();
+ // Initializer lists are also allowed, in C++11. Rely on the parser for the
+ // dialect distinction.
+ if (ResultType->isArrayType() || ArraySize) {
+ if (!isLegalArrayNewInitializer(initStyle, Initializer)) {
+ SourceRange InitRange(Inits[0]->getLocStart(),
+ Inits[NumInits - 1]->getLocEnd());
+ Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
+ return ExprError();
+ }
+ if (InitListExpr *ILE = dyn_cast_or_null<InitListExpr>(Initializer)) {
+ // We do the initialization typechecking against the array type
+ // corresponding to the number of initializers + 1 (to also check
+ // default-initialization).
+ unsigned NumElements = ILE->getNumInits() + 1;
+ InitType = Context.getConstantArrayType(AllocType,
+ llvm::APInt(Context.getTypeSize(Context.getSizeType()), NumElements),
+ ArrayType::Normal, 0);
+ }
}
if (!AllocType->isDependentType() &&
@@ -1270,7 +1289,7 @@
DirectInitRange.getEnd());
InitializedEntity Entity
- = InitializedEntity::InitializeNew(StartLoc, AllocType);
+ = InitializedEntity::InitializeNew(StartLoc, InitType);
InitializationSequence InitSeq(*this, Entity, Kind, Inits, NumInits);
ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind,
MultiExprArg(Inits, NumInits));
Modified: cfe/trunk/test/SemaCXX/new-delete-cxx0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/new-delete-cxx0x.cpp?rev=150688&r1=150687&r2=150688&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/new-delete-cxx0x.cpp (original)
+++ cfe/trunk/test/SemaCXX/new-delete-cxx0x.cpp Thu Feb 16 06:59:47 2012
@@ -7,3 +7,20 @@
(void)new int[-1]; // expected-warning {{array size is negative}}
(void)new int[2000000000]; // expected-warning {{array is too large}}
}
+
+
+struct S {
+ S(int);
+ S();
+ ~S();
+};
+
+struct T { // expected-note 2 {{not viable}}
+ T(int); // expected-note {{not viable}}
+};
+
+void fn() {
+ (void) new int[2] {1, 2};
+ (void) new S[2] {1, 2};
+ (void) new T[2] {1, 2}; // expected-error {{no matching constructor}}
+}
More information about the cfe-commits
mailing list