[PATCH] D117391: [AST] Ignore implicit nodes in CastExpr::getConversionFunction
Kim Gräsman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Sun Jan 16 07:48:46 PST 2022
kimgr updated this revision to Diff 400381.
kimgr added a comment.
Fix spurious semicolon
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D117391/new/
https://reviews.llvm.org/D117391
Files:
clang/lib/AST/Expr.cpp
clang/unittests/Tooling/CastExprTest.cpp
Index: clang/unittests/Tooling/CastExprTest.cpp
===================================================================
--- clang/unittests/Tooling/CastExprTest.cpp
+++ clang/unittests/Tooling/CastExprTest.cpp
@@ -14,12 +14,19 @@
struct CastExprVisitor : TestVisitor<CastExprVisitor> {
std::function<void(ExplicitCastExpr *)> OnExplicitCast;
+ std::function<void(CastExpr *)> OnCast;
bool VisitExplicitCastExpr(ExplicitCastExpr *Expr) {
if (OnExplicitCast)
OnExplicitCast(Expr);
return true;
}
+
+ bool VisitCastExpr(CastExpr *Expr) {
+ if (OnCast)
+ OnCast(Expr);
+ return true;
+ }
};
TEST(CastExprTest, GetSubExprAsWrittenThroughMaterializedTemporary) {
@@ -54,4 +61,57 @@
CastExprVisitor::Lang_CXX2a);
}
+// Verify that getConversionFunction looks through a ConstantExpr for implicit
+// constructor conversions (https://github.com/llvm/llvm-project/issues/53044):
+//
+// `-ImplicitCastExpr 'S' <ConstructorConversion>
+// `-ConstantExpr 'S'
+// |-value: Struct
+// `-CXXConstructExpr 'S' 'void (const char *)'
+// `-ImplicitCastExpr 'const char *' <ArrayToPointerDecay>
+// `-StringLiteral 'const char [7]' lvalue "foobar"
+TEST(CastExprTest, GetCtorConversionFunctionThroughConstantExpr) {
+ CastExprVisitor Visitor;
+ Visitor.OnCast = [](CastExpr *Expr) {
+ if (Expr->getCastKind() == CK_ConstructorConversion) {
+ auto *Conv = Expr->getConversionFunction();
+ EXPECT_TRUE(isa<CXXConstructorDecl>(Conv))
+ << "Expected CXXConstructorDecl, but saw " << Conv->getDeclKindName();
+ }
+ };
+ Visitor.runOver("struct X { consteval X(const char *) {} };\n"
+ "void f() { X x = \"foobar\"; }\n",
+ CastExprVisitor::Lang_CXX2a);
+}
+
+// Verify that getConversionFunction looks through a ConstantExpr for implicit
+// user-defined conversions.
+//
+// `-ImplicitCastExpr 'const char *' <UserDefinedConversion>
+// `-ConstantExpr 'const char *'
+// |-value: LValue
+// `-CXXMemberCallExpr 'const char *'
+// `-MemberExpr '<bound member function type>' .operator const char *
+// `-DeclRefExpr 'const X' lvalue Var 'x' 'const X'
+TEST(CastExprTest, GetUserDefinedConversionFunctionThroughConstantExpr) {
+ CastExprVisitor Visitor;
+ Visitor.OnCast = [](CastExpr *Expr) {
+ if (Expr->getCastKind() == CK_UserDefinedConversion) {
+ auto *Conv = Expr->getConversionFunction();
+ EXPECT_TRUE(isa<CXXMethodDecl>(Conv))
+ << "Expected CXXMethodDecl, but saw " << Conv->getDeclKindName();
+ }
+ };
+ Visitor.runOver("struct X {\n"
+ " consteval operator const char *() const {\n"
+ " return nullptr;\n"
+ " }\n"
+ "};\n"
+ "const char *f() {\n"
+ " constexpr X x;\n"
+ " return x;\n"
+ "}\n",
+ CastExprVisitor::Lang_CXX2a);
+}
+
} // namespace
Index: clang/lib/AST/Expr.cpp
===================================================================
--- clang/lib/AST/Expr.cpp
+++ clang/lib/AST/Expr.cpp
@@ -1944,6 +1944,7 @@
for (const CastExpr *E = this; E; E = dyn_cast<ImplicitCastExpr>(SubExpr)) {
SubExpr = skipImplicitTemporary(E->getSubExpr());
+ SubExpr = SubExpr->IgnoreImplicit();
if (E->getCastKind() == CK_ConstructorConversion)
return cast<CXXConstructExpr>(SubExpr)->getConstructor();
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117391.400381.patch
Type: text/x-patch
Size: 3469 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220116/1a1dada0/attachment.bin>
More information about the cfe-commits
mailing list