r288563 - DR616, and part of P0135R1: member access (or pointer-to-member access) on a

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Fri Dec 2 17:14:33 PST 2016


Author: rsmith
Date: Fri Dec  2 19:14:32 2016
New Revision: 288563

URL: http://llvm.org/viewvc/llvm-project?rev=288563&view=rev
Log:
DR616, and part of P0135R1: member access (or pointer-to-member access) on a
temporary produces an xvalue, not a prvalue. Support this by materializing the
temporary prior to performing the member access.

Modified:
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Analysis/ThreadSafety.cpp
    cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprCXX.cpp
    cfe/trunk/lib/Sema/SemaExprMember.cpp
    cfe/trunk/lib/Sema/SemaInit.cpp
    cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
    cfe/trunk/test/CXX/drs/dr4xx.cpp
    cfe/trunk/test/CXX/drs/dr6xx.cpp
    cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
    cfe/trunk/test/CodeGenCXX/compound-literals.cpp
    cfe/trunk/test/SemaCXX/constexpr-value-init.cpp
    cfe/trunk/test/SemaCXX/expression-traits.cpp
    cfe/trunk/test/SemaObjC/assign-rvalue-message.m
    cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
    cfe/trunk/www/cxx_dr_status.html

Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Fri Dec  2 19:14:32 2016
@@ -839,6 +839,11 @@ public:
   const Expr *skipRValueSubobjectAdjustments(
       SmallVectorImpl<const Expr *> &CommaLHS,
       SmallVectorImpl<SubobjectAdjustment> &Adjustments) const;
+  const Expr *skipRValueSubobjectAdjustments() const {
+    SmallVector<const Expr *, 8> CommaLHSs;
+    SmallVector<SubobjectAdjustment, 8> Adjustments;
+    return skipRValueSubobjectAdjustments(CommaLHSs, Adjustments);
+  }
 
   static bool classof(const Stmt *T) {
     return T->getStmtClass() >= firstExprConstant &&

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri Dec  2 19:14:32 2016
@@ -8715,6 +8715,11 @@ public:
   // argument, and arguments that have type float are promoted to double.
   ExprResult DefaultArgumentPromotion(Expr *E);
 
+  /// If \p E is a prvalue denoting an unmaterialized temporary, materialize
+  /// it as an xvalue. In C++98, the result will still be a prvalue, because
+  /// we don't have xvalues there.
+  ExprResult TemporaryMaterializationConversion(Expr *E);
+
   // Used for emitting the right warning by DefaultVariadicArgumentPromotion
   enum VariadicCallType {
     VariadicFunction,

Modified: cfe/trunk/lib/Analysis/ThreadSafety.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafety.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafety.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafety.cpp Fri Dec  2 19:14:32 2016
@@ -1583,7 +1583,7 @@ void BuildLockset::warnIfMutexHeld(const
 /// a pointer marked with pt_guarded_by.
 void BuildLockset::checkAccess(const Expr *Exp, AccessKind AK,
                                ProtectedOperationKind POK) {
-  Exp = Exp->IgnoreParenCasts();
+  Exp = Exp->IgnoreImplicit()->IgnoreParenCasts();
 
   SourceLocation Loc = Exp->getExprLoc();
 

Modified: cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp (original)
+++ cfe/trunk/lib/Analysis/ThreadSafetyCommon.cpp Fri Dec  2 19:14:32 2016
@@ -233,6 +233,9 @@ til::SExpr *SExprBuilder::translate(cons
     return translate(cast<ExprWithCleanups>(S)->getSubExpr(), Ctx);
   case Stmt::CXXBindTemporaryExprClass:
     return translate(cast<CXXBindTemporaryExpr>(S)->getSubExpr(), Ctx);
+  case Stmt::MaterializeTemporaryExprClass:
+    return translate(cast<MaterializeTemporaryExpr>(S)->GetTemporaryExpr(),
+                     Ctx);
 
   // Collect all literals
   case Stmt::CharacterLiteralClass:

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Fri Dec  2 19:14:32 2016
@@ -9810,8 +9810,8 @@ static bool IsReadonlyMessage(Expr *E, S
   const MemberExpr *ME = dyn_cast<MemberExpr>(E);
   if (!ME) return false;
   if (!isa<FieldDecl>(ME->getMemberDecl())) return false;
-  ObjCMessageExpr *Base =
-    dyn_cast<ObjCMessageExpr>(ME->getBase()->IgnoreParenImpCasts());
+  ObjCMessageExpr *Base = dyn_cast<ObjCMessageExpr>(
+      ME->getBase()->IgnoreImplicit()->IgnoreParenImpCasts());
   if (!Base) return false;
   return Base->getMethodDecl() != nullptr;
 }
@@ -9894,7 +9894,7 @@ static void DiagnoseConstAssignment(Sema
   while (true) {
     IsDereference = NextIsDereference;
 
-    E = E->IgnoreParenImpCasts();
+    E = E->IgnoreImplicit()->IgnoreParenImpCasts();
     if (const MemberExpr *ME = dyn_cast<MemberExpr>(E)) {
       NextIsDereference = ME->isArrow();
       const ValueDecl *VD = ME->getMemberDecl();

Modified: cfe/trunk/lib/Sema/SemaExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprCXX.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprCXX.cpp Fri Dec  2 19:14:32 2016
@@ -4984,11 +4984,14 @@ QualType Sema::CheckPointerToMemberOpera
          !RHS.get()->getType()->isPlaceholderType() &&
          "placeholders should have been weeded out by now");
 
-  // The LHS undergoes lvalue conversions if this is ->*.
-  if (isIndirect) {
+  // The LHS undergoes lvalue conversions if this is ->*, and undergoes the
+  // temporary materialization conversion otherwise.
+  if (isIndirect)
     LHS = DefaultLvalueConversion(LHS.get());
-    if (LHS.isInvalid()) return QualType();
-  }
+  else if (LHS.get()->isRValue())
+    LHS = TemporaryMaterializationConversion(LHS.get());
+  if (LHS.isInvalid())
+    return QualType();
 
   // The RHS always undergoes lvalue conversions.
   RHS = DefaultLvalueConversion(RHS.get());

Modified: cfe/trunk/lib/Sema/SemaExprMember.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprMember.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprMember.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprMember.cpp Fri Dec  2 19:14:32 2016
@@ -969,6 +969,15 @@ Sema::BuildMemberReferenceExpr(Expr *Bas
     BaseType = BaseType->castAs<PointerType>()->getPointeeType();
   }
   R.setBaseObjectType(BaseType);
+
+  // C++1z [expr.ref]p2:
+  //   For the first option (dot) the first expression shall be a glvalue [...]
+  if (!IsArrow && BaseExpr->isRValue()) {
+    ExprResult Converted = TemporaryMaterializationConversion(BaseExpr);
+    if (Converted.isInvalid())
+      return ExprError();
+    BaseExpr = Converted.get();
+  }
   
   LambdaScopeInfo *const CurLSI = getCurLambda();
   // If this is an implicit member reference and the overloaded

Modified: cfe/trunk/lib/Sema/SemaInit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaInit.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaInit.cpp (original)
+++ cfe/trunk/lib/Sema/SemaInit.cpp Fri Dec  2 19:14:32 2016
@@ -5963,10 +5963,7 @@ performReferenceExtension(Expr *Init,
 
     // Step over any subobject adjustments; we may have a materialized
     // temporary inside them.
-    SmallVector<const Expr *, 2> CommaLHSs;
-    SmallVector<SubobjectAdjustment, 2> Adjustments;
-    Init = const_cast<Expr *>(
-        Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
+    Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
 
     // Per current approach for DR1376, look through casts to reference type
     // when performing lifetime extension.
@@ -5996,10 +5993,7 @@ performReferenceExtension(Expr *Init,
 static void performLifetimeExtension(Expr *Init,
                                      const InitializedEntity *ExtendingEntity) {
   // Dig out the expression which constructs the extended temporary.
-  SmallVector<const Expr *, 2> CommaLHSs;
-  SmallVector<SubobjectAdjustment, 2> Adjustments;
-  Init = const_cast<Expr *>(
-      Init->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments));
+  Init = const_cast<Expr *>(Init->skipRValueSubobjectAdjustments());
 
   if (CXXBindTemporaryExpr *BTE = dyn_cast<CXXBindTemporaryExpr>(Init))
     Init = BTE->getSubExpr();
@@ -6218,6 +6212,22 @@ Sema::CreateMaterializeTemporaryExpr(Qua
   return MTE;
 }
 
+ExprResult Sema::TemporaryMaterializationConversion(Expr *E) {
+  // In C++98, we don't want to implicitly create an xvalue.
+  // FIXME: This means that AST consumers need to deal with "prvalues" that
+  // denote materialized temporaries. Maybe we should add another ValueKind
+  // for "xvalue pretending to be a prvalue" for C++98 support.
+  if (!E->isRValue() || !getLangOpts().CPlusPlus11)
+    return E;
+
+  // C++1z [conv.rval]/1: T shall be a complete type.
+  QualType T = E->getType();
+  if (RequireCompleteType(E->getExprLoc(), T, diag::err_incomplete_type))
+    return ExprError();
+
+  return CreateMaterializeTemporaryExpr(E->getType(), E, false);
+}
+
 ExprResult
 InitializationSequence::Perform(Sema &S,
                                 const InitializedEntity &Entity,
@@ -6316,7 +6326,9 @@ InitializationSequence::Perform(Sema &S,
   if (Args.size() == 1 && Args[0]->getType()->isArrayType() &&
       Entity.getType()->isPointerType() &&
       InitializedEntityOutlivesFullExpression(Entity)) {
-    Expr *Init = Args[0];
+    const Expr *Init = Args[0]->skipRValueSubobjectAdjustments();
+    if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(Init))
+      Init = MTE->GetTemporaryExpr();
     Expr::LValueClassification Kind = Init->ClassifyLValue(S.Context);
     if (Kind == Expr::LV_ClassTemporary || Kind == Expr::LV_ArrayTemporary)
       S.Diag(Init->getLocStart(), diag::warn_temporary_array_to_pointer_decay)

Modified: cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp (original)
+++ cfe/trunk/test/Analysis/temp-obj-dtors-cfg-output.cpp Fri Dec  2 19:14:32 2016
@@ -1093,9 +1093,9 @@ int testConsistencyNestedNormalReturn(bo
 // CHECK:     1: int a;
 // CHECK:     2: NoReturn() (CXXConstructExpr, class NoReturn)
 // CHECK:     3: [B2.2] (BindTemporary)
-// CHECK:     4: [B2.3].f
-// CHECK:     5: [B2.4]()
-// CHECK:     6: ~NoReturn() (Temporary object destructor)
+// CHECK:     [[MEMBER:[45]]]: [B2.{{[34]}}].f
+// CHECK:     {{[56]}}: [B2.[[MEMBER]]]()
+// CHECK:     {{[67]}}: ~NoReturn() (Temporary object destructor)
 // CHECK:     Preds (1): B3
 // CHECK:     Succs (1): B0
 // CHECK:   [B0 (EXIT)]

Modified: cfe/trunk/test/CXX/drs/dr4xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr4xx.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr4xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr4xx.cpp Fri Dec  2 19:14:32 2016
@@ -327,7 +327,7 @@ namespace dr420 { // dr420: yes
 
 namespace dr421 { // dr421: yes
   struct X { X(); int n; int &r; };
-  int *p = &X().n; // expected-error {{taking the address of a temporary}}
+  int *p = &X().n; // expected-error-re {{{{taking the address of a temporary|cannot take the address of an rvalue}}}}
   int *q = &X().r;
 }
 

Modified: cfe/trunk/test/CXX/drs/dr6xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr6xx.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr6xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr6xx.cpp Fri Dec  2 19:14:32 2016
@@ -142,15 +142,21 @@ namespace dr615 { // dr615: yes
   static int n = f();
 }
 
-namespace dr616 { // dr616: no
+namespace dr616 { // dr616: 4.0
 #if __cplusplus >= 201103L
   struct S { int n; } s;
-  // FIXME: These should all be 'int &&'
-  using T = decltype(S().n);
-  using T = decltype(static_cast<S&&>(s).n);
-  using T = decltype(S().*&S::n); // expected-note 2{{previous}}
-  using T = decltype(static_cast<S&&>(s).*&S::n); // expected-error {{different type}}
-  using T = int&&; // expected-error {{different type}}
+  S f();
+  using T = decltype((S().n));
+  using T = decltype((static_cast<S&&>(s).n));
+  using T = decltype((f().n));
+  using T = decltype(S().*&S::n);
+  using T = decltype(static_cast<S&&>(s).*&S::n);
+  using T = decltype(f().*&S::n);
+  using T = int&&;
+
+  using U = decltype(S().n);
+  using U = decltype(static_cast<S&&>(s).n);
+  using U = int;
 #endif
 }
 

Modified: cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp (original)
+++ cfe/trunk/test/CXX/expr/expr.const/p2-0x.cpp Fri Dec  2 19:14:32 2016
@@ -33,11 +33,11 @@ struct NonConstexpr3 {
   int m : NonConstexpr2().n; // expected-error {{constant expression}} expected-note {{undefined constructor 'NonConstexpr2'}}
 };
 struct NonConstexpr4 {
-  NonConstexpr4(); // expected-note {{declared here}}
+  NonConstexpr4();
   int n;
 };
 struct NonConstexpr5 {
-  int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-constexpr constructor 'NonConstexpr4' cannot be used in a constant expression}}
+  int n : NonConstexpr4().n; // expected-error {{constant expression}} expected-note {{non-literal type 'NonConstexpr4' cannot be used in a constant expression}}
 };
 
 // - an invocation of an undefined constexpr function or an undefined
@@ -321,7 +321,7 @@ namespace LValueToRValue {
   //   temporary object whose lifetime has not ended, initialized with a
   //   constant expression;
   constexpr volatile S f() { return S(); }
-  static_assert(f().i, ""); // ok! there's no lvalue-to-rvalue conversion here!
+  static_assert(f().i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
   static_assert(((volatile const S&&)(S)0).i, ""); // expected-error {{constant expression}} expected-note {{read of volatile-qualified type}}
 }
 

Modified: cfe/trunk/test/CodeGenCXX/compound-literals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/compound-literals.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/compound-literals.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/compound-literals.cpp Fri Dec  2 19:14:32 2016
@@ -38,23 +38,33 @@ int g() {
   return v[0];
 }
 
+// GCC's compound-literals-in-C++ extension lifetime-extends a compound literal
+// (or a C++11 list-initialized temporary!) if:
+//  - it is at global scope
+//  - it has array type
+//  - it has a constant initializer
+
 struct Z { int i[3]; };
 int *p = (Z){ {1, 2, 3} }.i;
 // CHECK: define {{.*}}__cxx_global_var_init()
-// CHECK: store i32* getelementptr inbounds (%struct.Z, %struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p
+// CHECK: alloca %struct.Z
+// CHECK: store i32* %{{.*}}, i32** @p
 
+int *q = (int [5]){1, 2, 3, 4, 5};
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
+// CHECK: store i32* getelementptr inbounds ([5 x i32], [5 x i32]* @.compoundliteral, i32 0, i32 0), i32** @q
 
 int *PR21912_1 = (int []){};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1()
-// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.2, i32 0, i32 0), i32** @PR21912_1
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.2()
+// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.3, i32 0, i32 0), i32** @PR21912_1
 
 union PR21912Ty {
   long long l;
   double d;
 };
 union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}};
-// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3()
-// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2
+// CHECK-LABEL: define {{.*}}__cxx_global_var_init.4()
+// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.5 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2
 
 // This compound literal should have local scope.
 int computed_with_lambda = [] {

Modified: cfe/trunk/test/SemaCXX/constexpr-value-init.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/constexpr-value-init.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/constexpr-value-init.cpp (original)
+++ cfe/trunk/test/SemaCXX/constexpr-value-init.cpp Fri Dec  2 19:14:32 2016
@@ -34,7 +34,7 @@ struct V : virtual C {};
 template<typename T> struct Z : T {
   constexpr Z() : V() {}
 };
-constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{virtual base class}}
+constexpr int n = Z<V>().c; // expected-error {{constant expression}} expected-note {{non-literal type 'Z<V>'}}
 
 struct E {
   A a[2];

Modified: cfe/trunk/test/SemaCXX/expression-traits.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/expression-traits.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/expression-traits.cpp (original)
+++ cfe/trunk/test/SemaCXX/expression-traits.cpp Fri Dec  2 19:14:32 2016
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -fcxx-exceptions %s
+// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify -fcxx-exceptions %s
 
 //
 // Tests for "expression traits" intrinsics such as __is_lvalue_expr.

Modified: cfe/trunk/test/SemaObjC/assign-rvalue-message.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaObjC/assign-rvalue-message.m?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/test/SemaObjC/assign-rvalue-message.m (original)
+++ cfe/trunk/test/SemaObjC/assign-rvalue-message.m Fri Dec  2 19:14:32 2016
@@ -1,5 +1,6 @@
 // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
-// RUN: %clang_cc1 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -std=c++98 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -std=c++11 -x objective-c++ -triple x86_64-apple-darwin10 -fsyntax-only -verify -Wno-objc-root-class %s
 // rdar://9005189
 
 @interface Foo 
@@ -19,6 +20,6 @@ struct Bar {
 
 - (void)baz {
     bar.x = 0;
-    [self bar].x = 10; // expected-error {{assigning to 'readonly' return result of an Objective-C message not allowed}}
+    [self bar].x = 10; // expected-error-re {{{{assigning to 'readonly' return result of an Objective-C message not allowed|expression is not assignable}}}}
 }
 @end

Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp (original)
+++ cfe/trunk/unittests/ASTMatchers/ASTMatchersNodeTest.cpp Fri Dec  2 19:14:32 2016
@@ -594,7 +594,7 @@ TEST(MaterializeTemporaryExpr, MatchesTe
                materializeTemporaryExpr()));
 
   EXPECT_TRUE(
-    notMatches(ClassString +
+    matches(ClassString +
                  "string GetStringByValue();"
                    "void run() { int k = GetStringByValue().length(); }",
                materializeTemporaryExpr()));

Modified: cfe/trunk/www/cxx_dr_status.html
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/www/cxx_dr_status.html?rev=288563&r1=288562&r2=288563&view=diff
==============================================================================
--- cfe/trunk/www/cxx_dr_status.html (original)
+++ cfe/trunk/www/cxx_dr_status.html Fri Dec  2 19:14:32 2016
@@ -813,7 +813,7 @@
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#129">129</a></td>
     <td>CD3</td>
     <td>Stability of uninitialized auto variables</td>
-    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
+    <td class="svn" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
   <tr id="130">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#130">130</a></td>
@@ -1480,7 +1480,7 @@ accessible?</td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#240">240</a></td>
     <td>CD3</td>
     <td>Uninitialized values and undefined behavior</td>
-    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
+    <td class="svn" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
   <tr id="241">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#241">241</a></td>
@@ -1913,7 +1913,7 @@ of class templates</td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#312">312</a></td>
     <td>CD3</td>
     <td>“use” of invalid pointer value not defined</td>
-    <td class="none" align="center">Duplicate of <a href="#616">616</a></td>
+    <td class="svn" align="center">Duplicate of <a href="#616">616</a></td>
   </tr>
   <tr id="313">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#313">313</a></td>
@@ -3739,7 +3739,7 @@ and <I>POD class</I></td>
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#616">616</a></td>
     <td>CD3</td>
     <td>Definition of “indeterminate value”</td>
-    <td class="none" align="center">No</td>
+    <td class="svn" align="center">SVN</td>
   </tr>
   <tr class="open" id="617">
     <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#617">617</a></td>




More information about the cfe-commits mailing list