[cfe-commits] r157420 - in /cfe/trunk: lib/Sema/SemaExprCXX.cpp test/CXX/expr/p10-0x.cpp
Jordy Rose
jediknil at belkadan.com
Thu May 24 15:25:39 PDT 2012
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
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list