diff options
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateExpr.cpp | 20 | ||||
-rw-r--r-- | test/SemaTemplate/instantiate-expr-3.cpp | 15 |
3 files changed, 36 insertions, 1 deletions
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index bb85455ddc..d268658454 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -5043,7 +5043,7 @@ Sema::OwningExprResult Sema::ActOnChooseExpr(SourceLocation BuiltinLoc, assert((CondExpr && LHSExpr && RHSExpr) && "Missing type argument(s)"); QualType resType; - if (CondExpr->isValueDependent()) { + if (CondExpr->isTypeDependent() || CondExpr->isValueDependent()) { resType = Context.DependentTy; } else { // The conditional expression is required to be a constant expression. diff --git a/lib/Sema/SemaTemplateInstantiateExpr.cpp b/lib/Sema/SemaTemplateInstantiateExpr.cpp index ca19a3d32f..92a152c2e3 100644 --- a/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -58,6 +58,7 @@ namespace { OwningExprResult VisitStmtExpr(StmtExpr *E); OwningExprResult VisitTypesCompatibleExpr(TypesCompatibleExpr *E); OwningExprResult VisitShuffleVectorExpr(ShuffleVectorExpr *E); + OwningExprResult VisitChooseExpr(ChooseExpr *E); OwningExprResult VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E); OwningExprResult VisitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E); OwningExprResult VisitCXXTemporaryObjectExpr(CXXTemporaryObjectExpr *E); @@ -521,6 +522,25 @@ TemplateExprInstantiator::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { } Sema::OwningExprResult +TemplateExprInstantiator::VisitChooseExpr(ChooseExpr *E) { + OwningExprResult Cond = Visit(E->getCond()); + if (Cond.isInvalid()) + return SemaRef.ExprError(); + + OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(), TemplateArgs); + if (LHS.isInvalid()) + return SemaRef.ExprError(); + + OwningExprResult RHS = Visit(E->getRHS()); + if (RHS.isInvalid()) + return SemaRef.ExprError(); + + return SemaRef.ActOnChooseExpr(E->getBuiltinLoc(), + move(Cond), move(LHS), move(RHS), + E->getRParenLoc()); +} + +Sema::OwningExprResult TemplateExprInstantiator::VisitSizeOfAlignOfExpr(SizeOfAlignOfExpr *E) { bool isSizeOf = E->isSizeOf(); diff --git a/test/SemaTemplate/instantiate-expr-3.cpp b/test/SemaTemplate/instantiate-expr-3.cpp index abc2d92c6d..df2bdc4261 100644 --- a/test/SemaTemplate/instantiate-expr-3.cpp +++ b/test/SemaTemplate/instantiate-expr-3.cpp @@ -74,6 +74,7 @@ template struct StatementExpr0<N1::X>; // expected-note{{instantiation}} // __builtin_shufflevector // --------------------------------------------------------------------- typedef __attribute__(( ext_vector_type(2) )) double double2; + template<typename T, typename U, int N, int M> struct ShuffleVector0 { void f(T t, U u, double2 a, double2 b) { @@ -85,3 +86,17 @@ struct ShuffleVector0 { template struct ShuffleVector0<double2, double2, 2, 1>; template struct ShuffleVector0<double2, double2, 4, 3>; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// __builtin_choose_expr +// --------------------------------------------------------------------- +template<bool Cond, typename T, typename U, typename Result> +struct Choose0 { + void f(T t, U u) { + Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}} + } +}; + +template struct Choose0<true, int, float, int&>; +template struct Choose0<false, int, float, float&>; +template struct Choose0<true, int, float, float&>; // expected-note{{instantiation}} |