Skip to content

Commit

Permalink
[Clang] Fix a crash when an invalid immediate function call appears i…
Browse files Browse the repository at this point in the history
…n a cast

Fixes #64949

Reviewed By: Fznamznon, erichkeane, shafik

Differential Revision: https://reviews.llvm.org/D158733
  • Loading branch information
cor3ntin committed Aug 25, 2023
1 parent 79ff70f commit 6824d15
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
4 changes: 4 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,10 @@ Bug Fixes to C++ Support
of a binary comparision.
(`#64923 <https://github.com/llvm/llvm-project/issues/64923>_``)

- Fix a crash when an immediate invocation is not a constant expression
and appear in an implicit cast.
(`#64949 <https://github.com/llvm/llvm-project/issues/64949>`_).

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
- Fixed an import failure of recursive friend class template.
Expand Down
10 changes: 6 additions & 4 deletions clang/lib/Sema/SemaExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18352,15 +18352,17 @@ static void EvaluateAndDiagnoseImmediateInvocation(
SemaRef.FailedImmediateInvocations.insert(CE);
Expr *InnerExpr = CE->getSubExpr()->IgnoreImplicit();
if (auto *FunctionalCast = dyn_cast<CXXFunctionalCastExpr>(InnerExpr))
InnerExpr = FunctionalCast->getSubExpr();
InnerExpr = FunctionalCast->getSubExpr()->IgnoreImplicit();
FunctionDecl *FD = nullptr;
if (auto *Call = dyn_cast<CallExpr>(InnerExpr))
FD = cast<FunctionDecl>(Call->getCalleeDecl());
else if (auto *Call = dyn_cast<CXXConstructExpr>(InnerExpr))
FD = Call->getConstructor();
else
llvm_unreachable("unhandled decl kind");
assert(FD && FD->isImmediateFunction());
else if (auto *Cast = dyn_cast<CastExpr>(InnerExpr))
FD = dyn_cast_or_null<FunctionDecl>(Cast->getConversionFunction());

assert(FD && FD->isImmediateFunction() &&
"could not find an immediate function in this expression");
SemaRef.Diag(CE->getBeginLoc(), diag::err_invalid_consteval_call)
<< FD << FD->isConsteval();
if (auto Context =
Expand Down
24 changes: 24 additions & 0 deletions clang/test/SemaCXX/cxx2a-consteval.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1103,3 +1103,27 @@ void bar() {
// expected-note {{read of non-const variable 'bad' is not allowed in a constant expression}}
}
}

namespace GH64949 {
struct f {
int g; // expected-note 2{{subobject declared here}}
constexpr ~f() {}
};
class h {

public:
consteval h(char *) {}
consteval operator int() const { return 1; }
f i;
};

void test() { (int)h{nullptr}; }
// expected-error@-1 {{call to consteval function 'GH64949::h::h' is not a constant expression}}
// expected-note@-2 {{subobject 'g' is not initialized}}

int test2() { return h{nullptr}; }
// expected-error@-1 {{call to consteval function 'GH64949::h::h' is not a constant expression}}
// expected-note@-2 {{subobject 'g' is not initialized}}


}

0 comments on commit 6824d15

Please sign in to comment.