From: John McCall Date: Sun, 10 Apr 2011 19:13:55 +0000 (+0000) Subject: Simplify calling CheckPlaceholderExpr, converge on it in a few places, X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=fb8721ce4c6fef3739b1cbd1e38e3f1949462033;p=clang Simplify calling CheckPlaceholderExpr, converge on it in a few places, and move a vector-splat check to follow l-value conversion. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@129254 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index ccf99671a5..e931fb6603 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -2015,7 +2015,7 @@ public: bool isType, void *TyOrEx, const SourceRange &ArgRange); - ExprResult CheckPlaceholderExpr(Expr *E, SourceLocation Loc); + ExprResult CheckPlaceholderExpr(Expr *E); bool CheckVecStepExpr(Expr *E, SourceLocation OpLoc, SourceRange R); bool CheckUnaryExprOrTypeTraitOperand(QualType type, SourceLocation OpLoc, diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 989be96d21..31a772a5d8 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -1526,37 +1526,26 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, // a non-lvalue-reference target type does not lead to decay. // C++ 5.2.9p4: Any expression can be explicitly converted to type "cv void". if (CastTy->isVoidType()) { + Kind = CK_ToVoid; + ExprResult CastExprRes = IgnoredValueConversions(CastExpr); if (CastExprRes.isInvalid()) return ExprError(); CastExpr = CastExprRes.take(); - bool ret = false; // false is 'able to convert' + if (CastExpr->getType() == Context.OverloadTy) { ExprResult SingleFunctionExpr = ResolveAndFixSingleFunctionTemplateSpecialization( CastExpr, /* Decay Function to ptr */ false, /* Complain */ true, R, CastTy, diag::err_bad_cstyle_cast_overload); - - if (SingleFunctionExpr.isUsable()) { - CastExpr = SingleFunctionExpr.take(); - Kind = CK_ToVoid; - } - else - ret = true; + if (SingleFunctionExpr.isInvalid()) + return ExprError(); + CastExpr = SingleFunctionExpr.take(); } - else - Kind = CK_ToVoid; - return ret ? ExprError() : Owned(CastExpr); - } - // Case of AltiVec vector initialization with a single literal - if (CastTy->isVectorType() - && CastTy->getAs()->getVectorKind() == - VectorType::AltiVecVector - && (CastExpr->getType()->isIntegerType() - || CastExpr->getType()->isFloatingType())) { - Kind = CK_VectorSplat; + assert(!CastExpr->getType()->isPlaceholderType()); + return Owned(CastExpr); } @@ -1577,6 +1566,15 @@ Sema::CXXCheckCStyleCast(SourceRange R, QualType CastTy, ExprValueKind &VK, CastExpr = CastExprRes.take(); } + // AltiVec vector initialization with a single literal. + if (const VectorType *vecTy = CastTy->getAs()) + if (vecTy->getVectorKind() == VectorType::AltiVecVector + && (CastExpr->getType()->isIntegerType() + || CastExpr->getType()->isFloatingType())) { + Kind = CK_VectorSplat; + return Owned(CastExpr); + } + // C++ [expr.cast]p5: The conversions performed by // - a const_cast, // - a static_cast, diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 70d7c7af48..3ced0fe66d 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2915,7 +2915,7 @@ Sema::CreateUnaryExprOrTypeTraitExpr(Expr *E, SourceLocation OpLoc, Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0; isInvalid = true; } else if (E->getType()->isPlaceholderType()) { - ExprResult PE = CheckPlaceholderExpr(E, OpLoc); + ExprResult PE = CheckPlaceholderExpr(E); if (PE.isInvalid()) return ExprError(); return CreateUnaryExprOrTypeTraitExpr(PE.take(), OpLoc, ExprKind, R); } else { @@ -2977,7 +2977,7 @@ static QualType CheckRealImagOperand(Sema &S, ExprResult &V, SourceLocation Loc, return V.get()->getType(); // Test for placeholders. - ExprResult PR = S.CheckPlaceholderExpr(V.get(), Loc); + ExprResult PR = S.CheckPlaceholderExpr(V.get()); if (PR.isInvalid()) return QualType(); if (PR.get() != V.get()) { V = move(PR); @@ -4730,7 +4730,7 @@ static ExprResult rebuildUnknownAnyFunction(Sema &S, Expr *fn, argTypes.reserve(numArgs); for (unsigned i = 0; i != numArgs; ++i) { // Require all the sub-expression to not be placeholders. - ExprResult result = S.CheckPlaceholderExpr(args[i], SourceLocation()); + ExprResult result = S.CheckPlaceholderExpr(args[i]); if (result.isInvalid()) return ExprError(); args[i] = result.take(); @@ -5169,6 +5169,8 @@ ExprResult Sema::CheckCastTypes(SourceRange TyR, QualType castType, castType, VK, castExpr, Kind, BasePath, FunctionalStyle); + assert(!castExpr->getType()->isPlaceholderType()); + // We only support r-value casts in C. VK = VK_RValue; @@ -5555,11 +5557,11 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS, ExprR ExprValueKind &VK, ExprObjectKind &OK, SourceLocation QuestionLoc) { - ExprResult lhsResult = CheckPlaceholderExpr(LHS.get(), QuestionLoc); + ExprResult lhsResult = CheckPlaceholderExpr(LHS.get()); if (!lhsResult.isUsable()) return QualType(); LHS = move(lhsResult); - ExprResult rhsResult = CheckPlaceholderExpr(RHS.get(), QuestionLoc); + ExprResult rhsResult = CheckPlaceholderExpr(RHS.get()); if (!rhsResult.isUsable()) return QualType(); RHS = move(rhsResult); @@ -7841,8 +7843,8 @@ static QualType CheckCommaOperands(Sema &S, ExprResult &LHS, ExprResult &RHS, SourceLocation Loc) { S.DiagnoseUnusedExprResult(LHS.get()); - LHS = S.CheckPlaceholderExpr(LHS.take(), Loc); - RHS = S.CheckPlaceholderExpr(RHS.take(), Loc); + LHS = S.CheckPlaceholderExpr(LHS.take()); + RHS = S.CheckPlaceholderExpr(RHS.take()); if (LHS.isInvalid() || RHS.isInvalid()) return QualType(); @@ -7927,7 +7929,7 @@ static QualType CheckIncrementDecrementOperand(Sema &S, Expr *Op, S.Diag(OpLoc, diag::ext_integer_increment_complex) << ResType << Op->getSourceRange(); } else if (ResType->isPlaceholderType()) { - ExprResult PR = S.CheckPlaceholderExpr(Op, OpLoc); + ExprResult PR = S.CheckPlaceholderExpr(Op); if (PR.isInvalid()) return QualType(); return CheckIncrementDecrementOperand(S, PR.take(), VK, OpLoc, isInc, isPrefix); @@ -8088,7 +8090,7 @@ static QualType CheckAddressOfOperand(Sema &S, Expr *OrigOp, if (OrigOp->getType() == S.Context.OverloadTy) return S.Context.OverloadTy; - ExprResult PR = S.CheckPlaceholderExpr(OrigOp, OpLoc); + ExprResult PR = S.CheckPlaceholderExpr(OrigOp); if (PR.isInvalid()) return QualType(); OrigOp = PR.take(); @@ -8242,7 +8244,7 @@ static QualType CheckIndirectionOperand(Sema &S, Expr *Op, ExprValueKind &VK, OpTy->getAs()) Result = OPT->getPointeeType(); else { - ExprResult PR = S.CheckPlaceholderExpr(Op, OpLoc); + ExprResult PR = S.CheckPlaceholderExpr(Op); if (PR.isInvalid()) return QualType(); if (PR.take() != Op) return CheckIndirectionOperand(S, PR.take(), VK, OpLoc); @@ -8382,11 +8384,11 @@ ExprResult Sema::CreateBuiltinBinOp(SourceLocation OpLoc, // f == 0; // resolve f blindly // void (*p)(int); p = f; // resolve f using target if (Opc != BO_Assign) { - ExprResult resolvedLHS = CheckPlaceholderExpr(lhs.get(), OpLoc); + ExprResult resolvedLHS = CheckPlaceholderExpr(lhs.get()); if (!resolvedLHS.isUsable()) return ExprError(); lhs = move(resolvedLHS); - ExprResult resolvedRHS = CheckPlaceholderExpr(rhs.get(), OpLoc); + ExprResult resolvedRHS = CheckPlaceholderExpr(rhs.get()); if (!resolvedRHS.isUsable()) return ExprError(); rhs = move(resolvedRHS); } @@ -8748,7 +8750,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType = CheckAddressOfOperand(*this, Input.get(), OpLoc); break; case UO_Deref: { - ExprResult resolved = CheckPlaceholderExpr(Input.get(), OpLoc); + ExprResult resolved = CheckPlaceholderExpr(Input.get()); if (!resolved.isUsable()) return ExprError(); Input = move(resolved); Input = DefaultFunctionArrayLvalueConversion(Input.take()); @@ -8773,7 +8775,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, resultType->isPointerType()) break; else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take(), OpLoc); + Input = CheckPlaceholderExpr(Input.take()); if (Input.isInvalid()) return ExprError(); return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); } @@ -8795,7 +8797,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, else if (resultType->hasIntegerRepresentation()) break; else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take(), OpLoc); + Input = CheckPlaceholderExpr(Input.take()); if (Input.isInvalid()) return ExprError(); return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); } else { @@ -8820,7 +8822,7 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc, ScalarTypeToBooleanCastKind(resultType)); } } else if (resultType->isPlaceholderType()) { - Input = CheckPlaceholderExpr(Input.take(), OpLoc); + Input = CheckPlaceholderExpr(Input.take()); if (Input.isInvalid()) return ExprError(); return CreateBuiltinUnaryOp(OpLoc, Opc, Input.take()); } else { @@ -10312,7 +10314,7 @@ static ExprResult diagnoseUnknownAnyExpr(Sema &S, Expr *e) { /// Check for operands with placeholder types and complain if found. /// Returns true if there was an error and no recovery was possible. -ExprResult Sema::CheckPlaceholderExpr(Expr *E, SourceLocation Loc) { +ExprResult Sema::CheckPlaceholderExpr(Expr *E) { // Placeholder types are always *exactly* the appropriate builtin type. QualType type = E->getType(); diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index fb4ff7891f..7cfbc7e172 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -3987,30 +3987,9 @@ ExprResult Sema::ActOnFinishFullExpr(Expr *FE) { if (DiagnoseUnexpandedParameterPack(FullExpr.get())) return ExprError(); - // 13.4.1 ... An overloaded function name shall not be used without arguments - // in contexts other than those listed [i.e list of targets]. - // - // void foo(); void foo(int); - // template void fooT(); template void fooT(int); - - // Therefore these should error: - // foo; - // fooT; - - if (FullExpr.get()->getType() == Context.OverloadTy) { - ExprResult Fixed - = ResolveAndFixSingleFunctionTemplateSpecialization(FullExpr.get(), - /*DoFunctionPointerConversion=*/false, - /*Complain=*/true, - FullExpr.get()->getSourceRange(), - QualType(), - diag::err_addr_ovl_ambiguous); - if (Fixed.isInvalid()) - return ExprError(); - - FullExpr = Fixed.get(); - } - + FullExpr = CheckPlaceholderExpr(FullExpr.take()); + if (FullExpr.isInvalid()) + return ExprError(); FullExpr = IgnoredValueConversions(FullExpr.take()); if (FullExpr.isInvalid()) diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index fc2c8f7e1d..9c70d250dd 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -3332,7 +3332,7 @@ QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword, } QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) { - ExprResult ER = CheckPlaceholderExpr(E, Loc); + ExprResult ER = CheckPlaceholderExpr(E); if (ER.isInvalid()) return QualType(); E = ER.take(); @@ -3345,7 +3345,7 @@ QualType Sema::BuildTypeofExprType(Expr *E, SourceLocation Loc) { } QualType Sema::BuildDecltypeType(Expr *E, SourceLocation Loc) { - ExprResult ER = CheckPlaceholderExpr(E, Loc); + ExprResult ER = CheckPlaceholderExpr(E); if (ER.isInvalid()) return QualType(); E = ER.take(); diff --git a/test/CXX/over/over.over/p2-resolve-single-template-id.cpp b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp index f4a5e8f633..b1cc1e3cfa 100644 --- a/test/CXX/over/over.over/p2-resolve-single-template-id.cpp +++ b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp @@ -35,18 +35,18 @@ namespace DontAllowUnresolvedOverloadedExpressionInAnUnusedExpression void check() { one; // expected-warning {{expression result unused}} - two; // expected-error{{address of overloaded function}} + two; // expected-error{{cannot resolve overloaded function 'two' from context}} oneT; // expected-warning {{expression result unused}} - twoT; // expected-error {{address of overloaded function}} + twoT; // expected-error {{cannot resolve overloaded function 'twoT' from context}} } // check the template function case template void check() { one; // expected-warning {{expression result unused}} - two; // expected-error{{address of overloaded function}} + two; // expected-error{{cannot resolve overloaded function 'two' from context}} oneT; // expected-warning {{expression result unused}} - twoT; // expected-error {{address of overloaded function}} + twoT; // expected-error {{cannot resolve overloaded function 'twoT' from context}} } @@ -81,8 +81,8 @@ int main() { static_cast(oneT); } { (void)(oneT); } - { static_cast(two); } // expected-error {{address of overloaded}} - { (void)(two); } // expected-error {{address of overloaded}} + { static_cast(two); } // expected-error {{address of overloaded function 'two' cannot be static_cast to type 'void'}} + { (void)(two); } // expected-error {{address of overloaded function 'two' cannot be cast to type 'void'}} { static_cast(twoT); } { (void)(twoT); } diff --git a/test/SemaTemplate/resolve-single-template-id.cpp b/test/SemaTemplate/resolve-single-template-id.cpp index ff6f37f2bd..ef0a763076 100644 --- a/test/SemaTemplate/resolve-single-template-id.cpp +++ b/test/SemaTemplate/resolve-single-template-id.cpp @@ -29,9 +29,9 @@ template struct test { }; int main() { one; // expected-warning {{expression result unused}} - two; // expected-error {{address of overloaded}} + two; // expected-error {{cannot resolve overloaded function 'two' from context}} oneT; // expected-warning {{expression result unused}} - twoT; // expected-error {{address of overloaded}} + twoT; // expected-error {{cannot resolve overloaded function 'twoT' from context}} typeid(oneT); // expected-warning{{expression result unused}} sizeof(oneT); // expected-warning {{expression result unused}} sizeof(twoT); //expected-error {{cannot resolve overloaded function 'twoT' from context}}