Index: include/clang/AST/Expr.h =================================================================== --- include/clang/AST/Expr.h +++ include/clang/AST/Expr.h @@ -850,7 +850,8 @@ /// the LHSs of comma expressions and adjustments needed along the path. const Expr *skipRValueSubobjectAdjustments( SmallVectorImpl &CommaLHS, - SmallVectorImpl &Adjustments) const; + SmallVectorImpl &Adjustments, + bool CanSkipNoOpCasts = true) const; const Expr *skipRValueSubobjectAdjustments() const { SmallVector CommaLHSs; SmallVector Adjustments; Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -76,7 +76,8 @@ const Expr *Expr::skipRValueSubobjectAdjustments( SmallVectorImpl &CommaLHSs, - SmallVectorImpl &Adjustments) const { + SmallVectorImpl &Adjustments, + bool CanSkipNoOpCasts) const { const Expr *E = this; while (true) { E = E->IgnoreParens(); @@ -92,10 +93,16 @@ continue; } - if (CE->getCastKind() == CK_NoOp) { + if (CanSkipNoOpCasts && CE->getCastKind() == CK_NoOp) { E = CE->getSubExpr(); continue; } + // We can not skip CK_NoOp casts. ScalarExprEmitter::VisitCastExpr() needs + // to visit *all* casts. C++ explicit casts are modelled in AST as outer + // ExplicitCastExpr with CK_NoOp cast kind, and one or more child + // ImplicitCastExpr's. But for the ImplicitCastSanitizer, we need to be + // able to distinqush whether ImplicitCastExpr is implicit in source code, + // or it is part of ExplicitCastExpr. Thus we need to visit CK_NoOp casts. } else if (const MemberExpr *ME = dyn_cast(E)) { if (!ME->isArrow()) { assert(ME->getBase()->getType()->isRecordType()); Index: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -467,7 +467,8 @@ SmallVector CommaLHSs; SmallVector Adjustments; - E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); + E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments, + /*CanSkipNoOpCasts*/ false); for (const auto &Ignored : CommaLHSs) EmitIgnoredExpr(Ignored); Index: lib/CodeGen/CGExprConstant.cpp =================================================================== --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -1835,8 +1835,8 @@ assert(E->getStorageDuration() == SD_Static); SmallVector CommaLHSs; SmallVector Adjustments; - const Expr *Inner = E->GetTemporaryExpr() - ->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); + const Expr *Inner = E->GetTemporaryExpr()->skipRValueSubobjectAdjustments( + CommaLHSs, Adjustments, /*CanSkipNoOpCasts*/ false); return CGM.GetAddrOfGlobalTemporary(E, Inner); } Index: test/CodeGenCXX/const-init-cxx11.cpp =================================================================== --- test/CodeGenCXX/const-init-cxx11.cpp +++ test/CodeGenCXX/const-init-cxx11.cpp @@ -226,7 +226,7 @@ }; // This creates a non-const temporary and binds a reference to it. - // CHECK: @[[TEMP:.*]] = internal global {{.*}} { i32 5 }, align 4 + // CHECK: @[[TEMP:.*]] = internal constant {{.*}} { i32 5 }, align 4 // CHECK: @_ZN16LiteralReference3litE = constant {{.*}} @[[TEMP]], align 8 const Lit &lit = Lit(); Index: test/CodeGenCXX/cxx0x-initializer-references.cpp =================================================================== --- test/CodeGenCXX/cxx0x-initializer-references.cpp +++ test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -94,9 +94,9 @@ } void foo() { -// CHECK-LABEL: @_ZN7PR231653fooEv -// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev -// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE + // CHECK-LABEL: @_ZN7PR231653fooEv + // CHECK-NOT: call {{.*}} @_ZN7PR2316510ChildClassC1Ev + // CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE helper(ChildClass()); } Index: test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp =================================================================== --- test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -501,7 +501,7 @@ void PR22940_helper(const pair&) { } void PR22940() { // CHECK-LABEL: @_ZN9B197730107PR22940Ev - // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( + // CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE( PR22940_helper(pair()); }