Skip to content

[clang] Fix const eval of constexpr-unknown relational comparisons. #150088

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

efriedma-quic
Copy link
Collaborator

Like in other places, ignore the reference type of the base. (It might make sense to refactor this at some point.)

Fixes #150015.

Like in other places, ignore the reference type of the base.  (It might
make sense to refactor this at some point.)

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

llvmbot commented Jul 22, 2025

@llvm/pr-subscribers-clang

Author: Eli Friedman (efriedma-quic)

Changes

Like in other places, ignore the reference type of the base. (It might make sense to refactor this at some point.)

Fixes #150015.


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

2 Files Affected:

  • (modified) clang/lib/AST/ExprConstant.cpp (+4-3)
  • (modified) clang/test/SemaCXX/constant-expression-p2280r4.cpp (+13)
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 8797eaddd0e18..106ad30adf1e5 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -14631,8 +14631,9 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
     // - Otherwise pointer comparisons are unspecified.
     if (!LHSDesignator.Invalid && !RHSDesignator.Invalid && IsRelational) {
       bool WasArrayIndex;
-      unsigned Mismatch = FindDesignatorMismatch(
-          getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
+      unsigned Mismatch =
+          FindDesignatorMismatch(getType(LHSValue.Base).getNonReferenceType(),
+                                 LHSDesignator, RHSDesignator, WasArrayIndex);
       // At the point where the designators diverge, the comparison has a
       // specified value if:
       //  - we are comparing array indices
@@ -14676,7 +14677,7 @@ EvaluateComparisonBinaryOperator(EvalInfo &Info, const BinaryOperator *E,
     // compare pointers within the object in question; otherwise, the result
     // depends on where the object is located in memory.
     if (!LHSValue.Base.isNull() && IsRelational) {
-      QualType BaseTy = getType(LHSValue.Base);
+      QualType BaseTy = getType(LHSValue.Base).getNonReferenceType();
       if (BaseTy->isIncompleteType())
         return Error(E);
       CharUnits Size = Info.Ctx.getTypeSizeInChars(BaseTy);
diff --git a/clang/test/SemaCXX/constant-expression-p2280r4.cpp b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
index 16f5f823d26c1..3fb7bf28b1e8b 100644
--- a/clang/test/SemaCXX/constant-expression-p2280r4.cpp
+++ b/clang/test/SemaCXX/constant-expression-p2280r4.cpp
@@ -383,3 +383,16 @@ namespace enable_if_2 {
   }
 }
 }
+
+namespace GH150015 {
+  extern int (& c)[8]; // interpreter-note {{declared here}}
+  constexpr int x = c <= c+8; // interpreter-error {{constexpr variable 'x' must be initialized by a constant expression}} \
+                              // interpreter-note {{initializer of 'c' is unknown}}
+
+  struct X {};
+  struct Y {};
+  struct Z : X, Y {};
+  extern Z z;
+  constexpr int bases = (void*)(X*)&z <= (Y*)&z; // nointerpreter-error {{constexpr variable 'bases' must be initialized by a constant expression}} \
+                                                 // nointerpreter-note {{comparison of addresses of subobjects of different base classes has unspecified value}}
+}

Copy link
Collaborator

@shafik shafik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

unsigned Mismatch = FindDesignatorMismatch(
getType(LHSValue.Base), LHSDesignator, RHSDesignator, WasArrayIndex);
unsigned Mismatch =
FindDesignatorMismatch(getType(LHSValue.Base).getNonReferenceType(),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it makes sense to create a local and set it to the result of getType(LHSValue.Base).getNonReferenceType(), comment it and then use that in the two locations you just modified.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem with that is that it presumes LHSValue.Base is non-null. Which I don't think we actually guarantee at the point we'd want to declare the variable, so the the best I can do is something like auto GetBaseType = [&]{return getType(LHSValue.Base).getNonReferenceType(); };.

@efriedma-quic efriedma-quic merged commit bba8467 into llvm:main Jul 24, 2025
9 checks passed
mahesh-attarde pushed a commit to mahesh-attarde/llvm-project that referenced this pull request Jul 28, 2025
…lvm#150088)

Like in other places, ignore the reference type of the base. (It might
make sense to refactor this at some point.)

Fixes llvm#150015.
tru pushed a commit to llvmbot/llvm-project that referenced this pull request Jul 29, 2025
…lvm#150088)

Like in other places, ignore the reference type of the base. (It might
make sense to refactor this at some point.)

Fixes llvm#150015.

(cherry picked from commit bba8467)
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
Projects
None yet
Development

Successfully merging this pull request may close these issues.

SIGSEGV in EvaluateComparisonBinaryOperator -> clang::Decl::getKind
3 participants