Correct behavior for default mem-initializers used by inherited ctors.

This commit is contained in:
Dan Katz
2025-04-24 09:58:10 -04:00
parent cba0278488
commit 82ebef0585
3 changed files with 37 additions and 4 deletions

View File

@@ -989,6 +989,9 @@ static bool getParameterName(ParmVarDecl *PVD, std::string &Out) {
StringRef FirstNameSeen = PVD->getName();
unsigned ParamIdx = PVD->getFunctionScopeIndex();
// TODO(P2996): This will crash if we're in the trailing requires-clause of
// a function declaration, since the DeclContext is not the function but the
// TranslationUnitDecl.
FunctionDecl *FD = cast<FunctionDecl>(PVD->getDeclContext());
FD = FD->getMostRecentDecl();
@@ -1019,6 +1022,9 @@ static bool getParameterName(ParmVarDecl *PVD, std::string &Out) {
}
static ParmVarDecl *getMostRecentParmVarDecl(ParmVarDecl *PVD) {
// TODO(P2996): This will crash if we're in the trailing requires-clause of
// a function declaration, since the DeclContext is not the function but the
// TranslationUnitDecl.
FunctionDecl *FD = cast<FunctionDecl>(PVD->getDeclContext());
FD = FD->getMostRecentDecl();
return FD->getParamDecl(PVD->getFunctionScopeIndex());
@@ -5570,14 +5576,22 @@ bool current_access_context(APValue &Result, ASTContext &C, MetaActions &Meta,
SourceRange Range, ArrayRef<Expr *> Args,
Decl *ContainingDecl) {
assert(ResultTy == C.MetaInfoTy);
Decl *Ctx = nullptr;
StackLocationExpr *SLE = StackLocationExpr::Create(C, SourceRange(), 1);
if (!Evaluator(Result, SLE, true) || !Result.isReflection())
if (!Evaluator(Result, SLE, true) || !Result.isReflectedDecl())
return true;
else if (Result.getReflectedDecl() != nullptr)
return false;
else if (Ctx = Result.getReflectedDecl(); !Ctx)
Ctx = Meta.CurrentCtx();
return SetAndSucceed(Result, makeReflection(Meta.CurrentCtx()));
if (auto *Ctor = dyn_cast<CXXConstructorDecl>(Ctx);
Ctor && Ctor->isInheritingConstructor())
Ctx = cast<Decl>(Ctor->getDeclContext());
if (auto *RD = dyn_cast<CXXRecordDecl>(Ctx))
return SetAndSucceed(Result,
makeReflection(QualType(RD->getTypeForDecl(), 0)));
return SetAndSucceed(Result, makeReflection(Ctx));
}
bool is_accessible(APValue &Result, ASTContext &C, MetaActions &Meta,

View File

@@ -26,6 +26,7 @@
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
#include "llvm/Support/raw_ostream.h"
#include <iostream>
using namespace clang;
using namespace sema;

View File

@@ -339,4 +339,22 @@ static_assert(is_accessible(^^a,
std::meta::access_context::unprivileged()));
} // namespace anonymous_structs_unions
// ========================
// default_mem_initializers
// ========================
namespace default_mem_initializers {
struct A {
int a;
consteval A(int p) : a(p) {}
};
struct B : A {
using A::A;
consteval B(int p, int q) : A(p * q) {}
std::meta::info s = std::meta::access_context::current().scope();
};
static_assert(B(1).s == ^^B);
static_assert(is_constructor(B{1, 2}.s) && parent_of(B{1, 2}.s) == ^^B);
} // namespace default_mem_initializers
int main() { }