Some non-ASCII characters seem to have snuck in in your comments.
On May 24, 2012, at 18:04, Eli Friedman wrote: > Author: efriedma > Date: Thu May 24 17:04:19 2012 > New Revision: 157420 > > URL: http://llvm.org/viewvc/llvm-project?rev=157420&view=rev > Log: > Implement the C++11 discarded value expression rules for volatile lvalues. > <rdar://problem/10790820>. > > > Added: > cfe/trunk/test/CXX/expr/p10-0x.cpp > Modified: > cfe/trunk/lib/Sema/SemaExprCXX.cpp > > Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=157420&r1=157419&r2=157420&view=diff > ============================================================================== > --- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original) > +++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Thu May 24 17:04:19 2012 > @@ -5267,6 +5267,61 @@ > return BuildCXXNoexceptExpr(KeyLoc, Operand, RParen); > } > > +static bool IsSpecialDiscardedValue(Expr *E) { > + // In C++11, discarded-value expressions of a certain form are special, > + // according to [expr]p10: > + // The lvalue-to-rvalue conversion (4.1) is applied only if the > + // expression is an lvalue of volatile-qualified type and it has > + // one of the following forms: > + E = E->IgnoreParens(); > + > + // â id-expression (5.1.1), > + if (isa<DeclRefExpr>(E)) > + return true; > + > + // â subscripting (5.2.1), > + if (isa<ArraySubscriptExpr>(E)) > + return true; > + > + // â class member access (5.2.5), > + if (isa<MemberExpr>(E)) > + return true; > + > + // â indirection (5.3.1), > + if (UnaryOperator *UO = dyn_cast<UnaryOperator>(E)) > + if (UO->getOpcode() == UO_Deref) > + return true; > + > + if (BinaryOperator *BO = dyn_cast<BinaryOperator>(E)) { > + // â pointer-to-member operation (5.5), > + if (BO->isPtrMemOp()) > + return true; > + > + // â comma expression (5.18) where the right operand is one of the > above. > + if (BO->getOpcode() == BO_Comma) > + return IsSpecialDiscardedValue(BO->getRHS()); > + } > + > + // â conditional expression (5.16) where both the second and the third > + // operands are one of the above, or > + if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) > + return IsSpecialDiscardedValue(CO->getTrueExpr()) && > + IsSpecialDiscardedValue(CO->getFalseExpr()); > + // The related edge case of "*x ?: *x". > + if (BinaryConditionalOperator *BCO = > + dyn_cast<BinaryConditionalOperator>(E)) { > + if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(BCO->getTrueExpr())) > + return IsSpecialDiscardedValue(OVE->getSourceExpr()) && > + IsSpecialDiscardedValue(BCO->getFalseExpr()); > + } > + > + // Objective-C++ extensions to the rule. > + if (isa<PseudoObjectExpr>(E) || isa<ObjCIvarRefExpr>(E)) > + return true; > + > + return false; > +} > + > /// Perform the conversions required for an expression used in a > /// context that ignores the result. > ExprResult Sema::IgnoredValueConversions(Expr *E) { > @@ -5291,8 +5346,21 @@ > return Owned(E); > } > > - // Otherwise, this rule does not apply in C++, at least not for the moment. > - if (getLangOpts().CPlusPlus) return Owned(E); > + if (getLangOpts().CPlusPlus) { > + // The C++11 standard defines the notion of a discarded-value expression; > + // normally, we don't need to do anything to handle it, but if it is a > + // volatile lvalue with a special form, we perform an lvalue-to-rvalue > + // conversion. > + if (getLangOpts().CPlusPlus0x && E->isGLValue() && > + E->getType().isVolatileQualified() && > + IsSpecialDiscardedValue(E)) { > + ExprResult Res = DefaultLvalueConversion(E); > + if (Res.isInvalid()) > + return Owned(E); > + E = Res.take(); > + } > + return Owned(E); > + } > > // GCC seems to also exclude expressions of incomplete enum type. > if (const EnumType *T = E->getType()->getAs<EnumType>()) { > > Added: cfe/trunk/test/CXX/expr/p10-0x.cpp > URL: > http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/p10-0x.cpp?rev=157420&view=auto > ============================================================================== > --- cfe/trunk/test/CXX/expr/p10-0x.cpp (added) > +++ cfe/trunk/test/CXX/expr/p10-0x.cpp Thu May 24 17:04:19 2012 > @@ -0,0 +1,46 @@ > +// RUN: %clang_cc1 -emit-llvm -triple x86_64-pc-linux-gnu %s -o - -std=c++11 > | FileCheck %s > + > +volatile int g1; > +struct S { > + volatile int a; > +} g2; > + > +volatile int& refcall(); > + > +// CHECK: define void @_Z2f1PViPV1S > +void f1(volatile int *x, volatile S* s) { > + // We should perform the load in these cases. > + // CHECK: load volatile i32* > + (*x); > + // CHECK: load volatile i32* > + __extension__ g1; > + // CHECK: load volatile i32* > + s->a; > + // CHECK: load volatile i32* > + g2.a; > + // CHECK: load volatile i32* > + s->*(&S::a); > + // CHECK: load volatile i32* > + // CHECK: load volatile i32* > + x[0], 1 ? x[0] : *x; > + > + // CHECK: load volatile i32* > + // CHECK: load volatile i32* > + // CHECK: load volatile i32* > + *x ?: *x; > + > + // CHECK: load volatile i32* > + ({ *x; }); > + > + // CHECK-NOT: load volatile > + // CHECK: ret > +} > + > +// CHECK: define void @_Z2f2PVi > +// CHECK-NOT: load volatile > +// CHECK: ret > +void f2(volatile int *x) { > + // We shouldn't perform the load in these cases. > + refcall(); > + 1 ? refcall() : *x; > +} > > > _______________________________________________ > cfe-commits mailing list > [email protected] > http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
