diff options
-rw-r--r-- | lib/Sema/SemaExprMember.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 8 | ||||
-rw-r--r-- | lib/Sema/SemaTemplate.cpp | 11 | ||||
-rw-r--r-- | test/SemaCXX/constant-expression-cxx11.cpp | 28 |
4 files changed, 46 insertions, 2 deletions
diff --git a/lib/Sema/SemaExprMember.cpp b/lib/Sema/SemaExprMember.cpp index 5696e2386d..da099681cb 100644 --- a/lib/Sema/SemaExprMember.cpp +++ b/lib/Sema/SemaExprMember.cpp @@ -761,6 +761,7 @@ static MemberExpr *BuildMemberExpr(ASTContext &C, Expr *Base, bool isArrow, QualType Ty, ExprValueKind VK, ExprObjectKind OK, const TemplateArgumentListInfo *TemplateArgs = 0) { + assert((!isArrow || Base->isRValue()) && "-> base must be a pointer rvalue"); return MemberExpr::Create(C, Base, isArrow, SS.getWithLocInContext(C), Member, FoundDecl, MemberNameInfo, TemplateArgs, Ty, VK, OK); diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index f35b359f57..6dcfbbab84 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -639,6 +639,9 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, // If the LHS is not the same type as the condition, insert an implicit // cast. + // FIXME: In C++11, the value is a converted constant expression of the + // promoted type of the switch condition. + Lo = DefaultLvalueConversion(Lo).take(); Lo = ImpCastExprToType(Lo, CondType, CK_IntegralCast).take(); CS->setLHS(Lo); @@ -716,8 +719,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Hi->getLocStart(), diag::warn_case_value_overflow); - // If the LHS is not the same type as the condition, insert an implicit + // If the RHS is not the same type as the condition, insert an implicit // cast. + // FIXME: In C++11, the value is a converted constant expression of the + // promoted type of the switch condition. + Hi = DefaultLvalueConversion(Hi).take(); Hi = ImpCastExprToType(Hi, CondType, CK_IntegralCast).take(); CR->setRHS(Hi); diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp index d2641888bd..de0193c61d 100644 --- a/lib/Sema/SemaTemplate.cpp +++ b/lib/Sema/SemaTemplate.cpp @@ -3743,8 +3743,16 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, // enumeration type, integral promotions (4.5) and integral // conversions (4.7) are applied. QualType ParamType = InstantiatedParamType; - QualType ArgType = Arg->getType(); if (ParamType->isIntegralOrEnumerationType()) { + // FIXME: In C++11, the argument is a converted constant expression of the + // type of the template parameter. + ExprResult ArgResult = DefaultLvalueConversion(Arg); + if (ArgResult.isInvalid()) + return ExprError(); + Arg = ArgResult.take(); + + QualType ArgType = Arg->getType(); + // C++ [temp.arg.nontype]p1: // A template-argument for a non-type, non-template // template-parameter shall be one of: @@ -3868,6 +3876,7 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param, return Owned(Arg); } + QualType ArgType = Arg->getType(); DeclAccessPair FoundResult; // temporary for ResolveOverloadedFunction // C++0x [temp.arg.nontype]p5 bullets 2, 4 and 6 permit conversion diff --git a/test/SemaCXX/constant-expression-cxx11.cpp b/test/SemaCXX/constant-expression-cxx11.cpp new file mode 100644 index 0000000000..89955701e6 --- /dev/null +++ b/test/SemaCXX/constant-expression-cxx11.cpp @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s + +template<typename T> constexpr T id(const T &t) { return t; } + +struct MemberZero { + constexpr int zero() { return 0; } +}; + +namespace TemplateArgumentConversion { + template<int n> struct IntParam {}; + + using IntParam0 = IntParam<0>; + // FIXME: This should be accepted once we do constexpr function invocation. + using IntParam0 = IntParam<id(0)>; // expected-error {{not an integral constant expression}} + using IntParam0 = IntParam<MemberZero().zero>; // expected-error {{did you mean to call it with no arguments?}} expected-error {{not an integral constant expression}} +} + +namespace CaseStatements { + void f(int n) { + switch (n) { + // FIXME: Produce the 'add ()' fixit for this. + case MemberZero().zero: // desired-error {{did you mean to call it with no arguments?}} expected-error {{not an integer constant expression}} + // FIXME: This should be accepted once we do constexpr function invocation. + case id(1): // expected-error {{not an integer constant expression}} + return; + } + } +} |