[PATCH] D154559: [clang] Fix constant evaluation about static member function
Yaxun Liu via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jul 5 19:27:44 PDT 2023
yaxunl created this revision.
yaxunl added reviewers: rjmccall, tra, rsmith.
Herald added a project: All.
yaxunl requested review of this revision.
Currently, clang does not allow static constexpr member
functions called through a const reference of an object
in constant expression, e.g. the following code
class static_multimap{
public:
static constexpr int size() noexcept{
return 8;
}
};
template <typename Map>
void test_non_shmem_pair_retrieve(Map& map){
auto constexpr cg_size = map.size();
}
int main(){
static_multimap map;
test_non_shmem_pair_retrieve(map);
return 0;
}
fails to compile with clang. (https://godbolt.org/z/T17vTWYcs)
This does not make sense since the evaluation of map.size
does not rely on map. The same code compiles with GCC.
https://reviews.llvm.org/D154559
Files:
clang/lib/AST/ExprConstant.cpp
clang/test/SemaCXX/constant-expression-cxx11.cpp
Index: clang/test/SemaCXX/constant-expression-cxx11.cpp
===================================================================
--- clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -2379,15 +2379,19 @@
template<typename T> void f1(T t) {
constexpr int k = t.size();
}
- template<typename T> void f2(const T &t) { // expected-note 2{{declared here}}
- constexpr int k = t.size(); // expected-error 2{{constant}} expected-note 2{{function parameter 't' with unknown value cannot be used in a constant expression}}
+ template<typename T> void f2a(const T &t) {
+ constexpr int k1 = t.size();
+ constexpr int k2 = (t).size();
+ }
+ template<typename T> void f2b(const T &t) { // expected-note {{declared here}}
+ constexpr int k = t.size(); // expected-error {{constant}} expected-note {{function parameter 't' with unknown value cannot be used in a constant expression}}
}
template<typename T> void f3(const T &t) {
constexpr int k = T::size();
}
void g(array<3> a) {
f1(a);
- f2(a); // expected-note {{instantiation of}}
+ f2a(a);
f3(a);
}
@@ -2396,7 +2400,7 @@
};
void h(array_nonstatic<3> a) {
f1(a);
- f2(a); // expected-note {{instantiation of}}
+ f2b(a); // expected-note {{instantiation of}}
}
}
Index: clang/lib/AST/ExprConstant.cpp
===================================================================
--- clang/lib/AST/ExprConstant.cpp
+++ clang/lib/AST/ExprConstant.cpp
@@ -8031,6 +8031,15 @@
/// Potentially visit a MemberExpr's base expression.
void VisitIgnoredBaseExpression(const Expr *E) {
+ // If E is a reference, and if so, there is no side effect.
+ if (const DeclRefExpr *DRE =
+ dyn_cast<DeclRefExpr>(E->IgnoreParenImpCasts())) {
+ if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
+ if (VD->getType()->isReferenceType()) {
+ return;
+ }
+ }
+ }
// While MSVC doesn't evaluate the base expression, it does diagnose the
// presence of side-effecting behavior.
if (Info.getLangOpts().MSVCCompat && !E->HasSideEffects(Info.Ctx))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D154559.537562.patch
Type: text/x-patch
Size: 2171 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230706/81080c4a/attachment.bin>
More information about the cfe-commits
mailing list