diff options
author | Douglas Gregor <dgregor@apple.com> | 2010-09-08 21:40:08 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2010-09-08 21:40:08 +0000 |
commit | 19311e70edaa2d7bb0d709344aebea4fbbae2da4 (patch) | |
tree | e0698436bd41b66e14c88789f6f809ab1c8700bf | |
parent | 56a965c0f77c9e6bffd65cc8f8796442a8527381 (diff) |
Use the new-initialization code for initializing scalars with a
function-style cast. Previously, we had a (redundant, incorrect)
semantic-checking path for non-class types, which allowed
value-initialization of a reference type and then crashed.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@113415 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 46 | ||||
-rw-r--r-- | lib/Sema/SemaInit.cpp | 15 | ||||
-rw-r--r-- | test/SemaCXX/decl-expr-ambiguity.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/functional-cast.cpp | 5 | ||||
-rw-r--r-- | test/SemaCXX/qualified-id-lookup.cpp | 2 | ||||
-rw-r--r-- | test/SemaCXX/type-convert-construct.cpp | 2 |
6 files changed, 28 insertions, 44 deletions
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index c3e2c50312..5dc2713d64 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -615,41 +615,17 @@ Sema::BuildCXXTypeConstructExpr(TypeSourceInfo *TInfo, RParenLoc)); } - if (Ty->isRecordType()) { - InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); - InitializationKind Kind - = NumExprs ? InitializationKind::CreateDirect(TyBeginLoc, - LParenLoc, RParenLoc) - : InitializationKind::CreateValue(TyBeginLoc, - LParenLoc, RParenLoc); - InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); - ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs)); - - // FIXME: Improve AST representation? - return move(Result); - } - - // C++ [expr.type.conv]p1: - // If the expression list specifies more than a single value, the type shall - // be a class with a suitably declared constructor. - // - if (NumExprs > 1) - return ExprError(Diag(PP.getLocForEndOfToken(Exprs[0]->getLocEnd()), - diag::err_builtin_func_cast_more_than_one_arg) - << FullRange); - - assert(NumExprs == 0 && "Expected 0 expressions"); - // FIXME: Why doesn't this go through the new-initialization code? - - // C++ [expr.type.conv]p2: - // The expression T(), where T is a simple-type-specifier for a non-array - // complete object type or the (possibly cv-qualified) void type, creates an - // rvalue of the specified type, which is value-initialized. - // - exprs.release(); - return Owned(new (Context) CXXScalarValueInitExpr( - TInfo->getType().getNonLValueExprType(Context), - TInfo, RParenLoc)); + InitializedEntity Entity = InitializedEntity::InitializeTemporary(TInfo); + InitializationKind Kind + = NumExprs ? InitializationKind::CreateDirect(TyBeginLoc, + LParenLoc, RParenLoc) + : InitializationKind::CreateValue(TyBeginLoc, + LParenLoc, RParenLoc); + InitializationSequence InitSeq(*this, Entity, Kind, Exprs, NumExprs); + ExprResult Result = InitSeq.Perform(*this, Entity, Kind, move(exprs)); + + // FIXME: Improve AST representation? + return move(Result); } diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 64f5ac06b4..fe10422935 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -4094,13 +4094,18 @@ bool InitializationSequence::Diagnose(Sema &S, SourceRange R; if (InitListExpr *InitList = dyn_cast<InitListExpr>(Args[0])) - R = SourceRange(InitList->getInit(1)->getLocStart(), + R = SourceRange(InitList->getInit(0)->getLocEnd(), InitList->getLocEnd()); - else - R = SourceRange(Args[0]->getLocStart(), Args[NumArgs - 1]->getLocEnd()); + else + R = SourceRange(Args[0]->getLocEnd(), Args[NumArgs - 1]->getLocEnd()); - S.Diag(Kind.getLocation(), diag::err_excess_initializers) - << /*scalar=*/2 << R; + R.setBegin(S.PP.getLocForEndOfToken(R.getBegin())); + if (Kind.isCStyleOrFunctionalCast()) + S.Diag(Kind.getLocation(), diag::err_builtin_func_cast_more_than_one_arg) + << R; + else + S.Diag(Kind.getLocation(), diag::err_excess_initializers) + << /*scalar=*/2 << R; break; } diff --git a/test/SemaCXX/decl-expr-ambiguity.cpp b/test/SemaCXX/decl-expr-ambiguity.cpp index 4243c1c0ea..9595faece2 100644 --- a/test/SemaCXX/decl-expr-ambiguity.cpp +++ b/test/SemaCXX/decl-expr-ambiguity.cpp @@ -9,7 +9,7 @@ void f() { T(a)->m = 7; int(a)++; // expected-error {{expression is not assignable}} __extension__ int(a)++; // expected-error {{expression is not assignable}} - __typeof(int)(a,5)<<a; // expected-error {{function-style cast to a builtin type can only take one argument}} + __typeof(int)(a,5)<<a; // expected-error {{excess elements in scalar initializer}} void(a), ++a; if (int(a)+1) {} for (int(a)+1;;) {} // expected-warning {{expression result unused}} diff --git a/test/SemaCXX/functional-cast.cpp b/test/SemaCXX/functional-cast.cpp index 2f63c20385..61e4da3da9 100644 --- a/test/SemaCXX/functional-cast.cpp +++ b/test/SemaCXX/functional-cast.cpp @@ -23,7 +23,7 @@ void test_cxx_functional_value_init() { void test_cxx_function_cast_multi() { (void)NoValueInit(0, 0); (void)NoValueInit(0, 0, 0); // expected-error{{no matching constructor for initialization}} - (void)int(1, 2); // expected-error{{function-style cast to a builtin type can only take one argument}} + (void)int(1, 2); // expected-error{{excess elements in scalar initializer}} } @@ -314,4 +314,7 @@ void crash_on_invalid_1() { typedef itn Typo; // expected-error {{unknown type name 'itn'}} (void)Typo(1); // used to crash + + typedef int &int_ref; + (void)int_ref(); // expected-error {{reference to type 'int' requires an initializer}} } diff --git a/test/SemaCXX/qualified-id-lookup.cpp b/test/SemaCXX/qualified-id-lookup.cpp index dfb059aa36..3cd6e1894b 100644 --- a/test/SemaCXX/qualified-id-lookup.cpp +++ b/test/SemaCXX/qualified-id-lookup.cpp @@ -78,7 +78,7 @@ namespace a { typedef int f2_type(int, int); void test_f2() { - ::f2_type(1, 2); // expected-error {{function-style cast to a builtin type can only take one argument}} + ::f2_type(1, 2); // expected-error {{excess elements in scalar initializer}} } } diff --git a/test/SemaCXX/type-convert-construct.cpp b/test/SemaCXX/type-convert-construct.cpp index 8f92a035dc..479af21476 100644 --- a/test/SemaCXX/type-convert-construct.cpp +++ b/test/SemaCXX/type-convert-construct.cpp @@ -2,7 +2,7 @@ void f() { float v1 = float(1); - int v2 = typeof(int)(1,2); // expected-error {{function-style cast to a builtin type can only take one argument}} + int v2 = typeof(int)(1,2); // expected-error {{excess elements in scalar initializer}} typedef int arr[]; int v3 = arr(); // expected-error {{array types cannot be value-initialized}} int v4 = int(); |