diff options
| -rw-r--r-- | clang/lib/AST/Expr.cpp | 8 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateInstantiateExpr.cpp | 16 | ||||
| -rw-r--r-- | clang/test/SemaTemplate/instantiate-expr-3.cpp | 18 | 
3 files changed, 30 insertions, 12 deletions
| diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 6bafdf278d8..2df76a29048 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -828,16 +828,16 @@ Expr::isLvalueResult Expr::isLvalueInternal(ASTContext &Ctx) const {      // casts should be wrapped by ImplicitCastExprs. There's just the special      // case involving throws to work out.      const ConditionalOperator *Cond = cast<ConditionalOperator>(this); -    Expr *LHS = Cond->getLHS(); -    Expr *RHS = Cond->getRHS(); +    Expr *True = Cond->getTrueExpr(); +    Expr *False = Cond->getFalseExpr();      // C++0x 5.16p2      //   If either the second or the third operand has type (cv) void, [...]      //   the result [...] is an rvalue. -    if (LHS->getType()->isVoidType() || RHS->getType()->isVoidType()) +    if (True->getType()->isVoidType() || False->getType()->isVoidType())        return LV_InvalidExpression;      // Both sides must be lvalues for the result to be an lvalue. -    if (LHS->isLvalue(Ctx) != LV_Valid || RHS->isLvalue(Ctx) != LV_Valid) +    if (True->isLvalue(Ctx) != LV_Valid || False->isLvalue(Ctx) != LV_Valid)        return LV_InvalidExpression;      // That's it. diff --git a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp index 9dda383342c..2589e301e0d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateExpr.cpp @@ -427,13 +427,13 @@ TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {    if (Cond.isInvalid())      return SemaRef.ExprError(); -  // FIXME: use getLHS() and cope with NULLness -  Sema::OwningExprResult True = Visit(E->getTrueExpr()); -  if (True.isInvalid()) +  Sema::OwningExprResult LHS = SemaRef.InstantiateExpr(E->getLHS(),  +                                                       TemplateArgs); +  if (LHS.isInvalid())      return SemaRef.ExprError(); -  Sema::OwningExprResult False = Visit(E->getFalseExpr()); -  if (False.isInvalid()) +  Sema::OwningExprResult RHS = Visit(E->getRHS()); +  if (RHS.isInvalid())      return SemaRef.ExprError();    if (!E->isTypeDependent()) {  @@ -442,15 +442,15 @@ TemplateExprInstantiator::VisitConditionalOperator(ConditionalOperator *E) {      // Instead, we just build the new conditional operator call expression.      return SemaRef.Owned(new (SemaRef.Context) ConditionalOperator(                                                             Cond.takeAs<Expr>(), -                                                           True.takeAs<Expr>(),  -                                                           False.takeAs<Expr>(), +                                                           LHS.takeAs<Expr>(),  +                                                           RHS.takeAs<Expr>(),                                                             E->getType()));    }    return SemaRef.ActOnConditionalOp(/*FIXME*/E->getCond()->getLocEnd(),                                      /*FIXME*/E->getFalseExpr()->getLocStart(), -                                    move(Cond), move(True), move(False)); +                                    move(Cond), move(LHS), move(RHS));  }  Sema::OwningExprResult  diff --git a/clang/test/SemaTemplate/instantiate-expr-3.cpp b/clang/test/SemaTemplate/instantiate-expr-3.cpp index 892f649ef7a..7f54c5de3c3 100644 --- a/clang/test/SemaTemplate/instantiate-expr-3.cpp +++ b/clang/test/SemaTemplate/instantiate-expr-3.cpp @@ -1,5 +1,8 @@  // RUN: clang-cc -fsyntax-only -verify %s +// --------------------------------------------------------------------- +// Imaginary literals +// ---------------------------------------------------------------------  template<typename T>  struct ImaginaryLiteral0 {    void f(T &x) { @@ -10,6 +13,9 @@ struct ImaginaryLiteral0 {  template struct ImaginaryLiteral0<_Complex float>;  template struct ImaginaryLiteral0<int*>; // expected-note{{instantiation}} +// --------------------------------------------------------------------- +// Compound assignment operator +// ---------------------------------------------------------------------  namespace N1 {    struct X { }; @@ -38,3 +44,15 @@ template struct N2::PlusEquals0<N1::X, long, long&>;  template struct N2::PlusEquals0<N3::Y, long, short&>;  template struct N2::PlusEquals0<int, int, int&>;  template struct N2::PlusEquals0<N3::Y, int, short&>; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// Conditional operator +// --------------------------------------------------------------------- +template<typename T, typename U, typename Result> +struct Conditional0 { +  void f(T t, U u) { +    Result result = t? : u; +  } +}; + +template struct Conditional0<int, int, int>; | 

