Skip to content

[Clang][AST] Fix HandleLValueBase to deal with references #140105

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

shafik
Copy link
Collaborator

@shafik shafik commented May 15, 2025

Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to use getNonReferenceType() to obtain the Pointee Type if we have a reference.

Fixes: #139452

Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase
now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to use
getNonReferenceType() to obtain the Pointee Type if we have a reference.

Fixes: llvm#139452
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 15, 2025
@llvmbot
Copy link
Member

llvmbot commented May 15, 2025

@llvm/pr-subscribers-clang

Author: Shafik Yaghmour (shafik)

Changes

Since P2280R4 Unknown references and pointers was implemented, HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix is to use getNonReferenceType() to obtain the Pointee Type if we have a reference.

Fixes: #139452


Full diff: https://github.com/llvm/llvm-project/pull/140105.diff

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+5-1)
  • (modified) clang/test/SemaCXX/constant-expression-p2280r4.cpp (+21)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 31c517338c21f..25e3e4105b3f1 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -597,6 +597,8 @@ Bug Fixes in This Version
 - Fixed a crash with an invalid member function parameter list with a default
   argument which contains a pragma. (#GH113722)
 - Fixed assertion failures when generating name lookup table in modules. (#GH61065, #GH134739)
+- Fix crash due to unknown references and pointer implementation and handling of
+  base classes. (GH139452)
 
 Bug Fixes to Compiler Builtins
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 86dbb349fd1a7..ca1fbdf7e652f 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -3314,7 +3314,11 @@ static bool HandleLValueBase(EvalInfo &Info, const Expr *E, LValue &Obj,
     return false;
 
   // Extract most-derived object and corresponding type.
-  DerivedDecl = D.MostDerivedType->getAsCXXRecordDecl();
+  // FIXME: After implementing P2280R4 it became possible to get references
+  // here. We do MostDerivedType->getAsCXXRecordDecl() in several other
+  // locations and if we see crashes in those locations in the future
+  // it may make more sense to move this fix into Lvalue::set.
+  DerivedDecl = D.MostDerivedType.getNonReferenceType()->getAsCXXRecordDecl();
   if (!CastToDerivedClass(Info, E, Obj, DerivedDecl, D.MostDerivedPathLength))
     return false;
 
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 0cdc16ed4e822..88e0a8f153b10 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -178,3 +178,24 @@ namespace extern_reference_used_as_unknown {
   int y;
   constinit int& g = (x,y); // expected-warning {{left operand of comma operator has no effect}}
 }
+
+namespace GH139452 {
+struct Dummy {
+  explicit operator bool() const noexcept { return true; }
+};
+
+struct Base { int error; };
+struct Derived : virtual Base { };
+
+template <class R>
+constexpr R get_value() {
+    const auto& derived_val = Derived{};
+    if (derived_val.error != 0)
+        /* nothing */;
+    return R{};
+}
+
+int f() {
+    return !get_value<Dummy>(); // contextually convert the function call result to bool
+}
+}

@shafik shafik merged commit 136f2ba into llvm:main May 15, 2025
12 checks passed
@frederick-vs-ja frederick-vs-ja added this to the LLVM 20.X Release milestone May 16, 2025
@github-project-automation github-project-automation bot moved this to Needs Triage in LLVM Release Status May 16, 2025
@frederick-vs-ja
Copy link
Contributor

/cherry-pick 136f2ba

@llvmbot
Copy link
Member

llvmbot commented May 16, 2025

Failed to cherry-pick: 136f2ba

https://github.com/llvm/llvm-project/actions/runs/15067591667

Please manually backport the fix and push it to your github fork. Once this is done, please create a pull request

frederick-vs-ja pushed a commit to frederick-vs-ja/llvm-project that referenced this pull request May 16, 2025
Since P2280R4 Unknown references and pointers was implemented,
HandleLValueBase now has to deal with referneces:

D.MostDerivedType->getAsCXXRecordDecl()

will return a nullptr if D.MostDerivedType is a ReferenceType. The fix
is to use getNonReferenceType() to obtain the Pointee Type if we have a
reference.

Fixes: llvm#139452
(cherry picked from commit 136f2ba)

# Conflicts:
#	clang/docs/ReleaseNotes.rst
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category release:cherry-pick-failed
Projects
Status: Needs Triage
Development

Successfully merging this pull request may close these issues.

Clang crash after "Implement P2280R4 Using unknown pointers and references in constant expressions"
4 participants