lebedev.ri created this revision. lebedev.ri added reviewers: rsmith, rjmccall, majnemer, efriedma. Herald added a subscriber: cfe-commits.
As discussed in PR38166 <https://bugs.llvm.org/show_bug.cgi?id=38166>, we need to be able to distinqush whether the cast we are visiting is actually a cast, or part of an `ExplicitCast`. There are at least two ways to get there: 1. Introduce a new `CastKind`, and use it instead of `IntegralCast` if we are in `ExplicitCast`. Would work, but does not scale - what if we will need more of these cast kinds? 2. Fix `ScalarExprEmitter::VisitCastExpr()` to visit these `NoOp` casts. As pointed out by @rsmith, CodeGenFunction::EmitMaterializeTemporaryExpr calls skipRValueSubobjectAdjustments, which steps over the CK_NoOp cast`, which explains why we currently don't visit those. Now, the problem is, this is a very specific area of clang. I'm not familiar with it. At first, when i saw these test regressions, i immediately panicked, But now that i have actually looked at them in detail, at least in the case of `test/CodeGenCXX/cxx0x-initializer-*`, as far as i can tell, only the IR is different, the assembly is still exactly the same. Or i'm really failing to look.. So i'm not sure whether these test changes are really ok or not, thus i'm posting this differential. Repository: rC Clang https://reviews.llvm.org/D49508 Files: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGExprConstant.cpp test/CodeGenCXX/const-init-cxx11.cpp test/CodeGenCXX/cxx0x-initializer-references.cpp test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp
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*, int>&) { } void PR22940() { // CHECK-LABEL: @_ZN9B197730107PR22940Ev - // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( + // CHECK-NOT: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE( PR22940_helper(pair<void*, int>()); } 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/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: lib/CodeGen/CGExprConstant.cpp =================================================================== --- lib/CodeGen/CGExprConstant.cpp +++ lib/CodeGen/CGExprConstant.cpp @@ -1835,8 +1835,8 @@ assert(E->getStorageDuration() == SD_Static); SmallVector<const Expr *, 2> CommaLHSs; SmallVector<SubobjectAdjustment, 2> 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: lib/CodeGen/CGExpr.cpp =================================================================== --- lib/CodeGen/CGExpr.cpp +++ lib/CodeGen/CGExpr.cpp @@ -467,7 +467,8 @@ SmallVector<const Expr *, 2> CommaLHSs; SmallVector<SubobjectAdjustment, 2> Adjustments; - E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments); + E = E->skipRValueSubobjectAdjustments(CommaLHSs, Adjustments, + /*CanSkipNoOpCasts*/ false); for (const auto &Ignored : CommaLHSs) EmitIgnoredExpr(Ignored); Index: lib/AST/Expr.cpp =================================================================== --- lib/AST/Expr.cpp +++ lib/AST/Expr.cpp @@ -76,7 +76,8 @@ const Expr *Expr::skipRValueSubobjectAdjustments( SmallVectorImpl<const Expr *> &CommaLHSs, - SmallVectorImpl<SubobjectAdjustment> &Adjustments) const { + SmallVectorImpl<SubobjectAdjustment> &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<MemberExpr>(E)) { if (!ME->isArrow()) { assert(ME->getBase()->getType()->isRecordType()); 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<const Expr *> &CommaLHS, - SmallVectorImpl<SubobjectAdjustment> &Adjustments) const; + SmallVectorImpl<SubobjectAdjustment> &Adjustments, + bool CanSkipNoOpCasts = true) const; const Expr *skipRValueSubobjectAdjustments() const { SmallVector<const Expr *, 8> CommaLHSs; SmallVector<SubobjectAdjustment, 8> Adjustments;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits