forked from OSchip/llvm-project
When attempting to complete an incomplete array bound type in an expression,
update the type from the definition even if we didn't instantiate a definition. We may have instantiated the definition in an earlier stage of semantic analysis, after creating the DeclRefExpr but before we reach a point where a complete expression type is required. llvm-svn: 320709
This commit is contained in:
parent
12cdb4fd33
commit
2faf8e127f
|
@ -7268,27 +7268,29 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|||
void Sema::completeExprArrayBound(Expr *E) {
|
||||
if (DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(E->IgnoreParens())) {
|
||||
if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
|
||||
if (isTemplateInstantiation(Var->getTemplateSpecializationKind()) &&
|
||||
!Var->getDefinition()) {
|
||||
SourceLocation PointOfInstantiation = E->getExprLoc();
|
||||
InstantiateVariableDefinition(PointOfInstantiation, Var);
|
||||
if (isTemplateInstantiation(Var->getTemplateSpecializationKind())) {
|
||||
auto *Def = Var->getDefinition();
|
||||
if (!Def) {
|
||||
SourceLocation PointOfInstantiation = E->getExprLoc();
|
||||
InstantiateVariableDefinition(PointOfInstantiation, Var);
|
||||
Def = Var->getDefinition();
|
||||
|
||||
// If we don't already have a point of instantiation, and we managed to
|
||||
// instantiate a definition, this is the point of instantiation.
|
||||
// Otherwise, we don't request an end-of-TU instantiation, so this is
|
||||
// not a point of instantiation.
|
||||
// FIXME: Is this really the right behavior?
|
||||
if (Var->getPointOfInstantiation().isInvalid() && Def) {
|
||||
assert(Var->getTemplateSpecializationKind() ==
|
||||
TSK_ImplicitInstantiation &&
|
||||
"explicit instantiation with no point of instantiation");
|
||||
Var->setTemplateSpecializationKind(
|
||||
Var->getTemplateSpecializationKind(), PointOfInstantiation);
|
||||
// If we don't already have a point of instantiation, and we managed
|
||||
// to instantiate a definition, this is the point of instantiation.
|
||||
// Otherwise, we don't request an end-of-TU instantiation, so this is
|
||||
// not a point of instantiation.
|
||||
// FIXME: Is this really the right behavior?
|
||||
if (Var->getPointOfInstantiation().isInvalid() && Def) {
|
||||
assert(Var->getTemplateSpecializationKind() ==
|
||||
TSK_ImplicitInstantiation &&
|
||||
"explicit instantiation with no point of instantiation");
|
||||
Var->setTemplateSpecializationKind(
|
||||
Var->getTemplateSpecializationKind(), PointOfInstantiation);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the type to the newly instantiated definition's type both
|
||||
// here and within the expression.
|
||||
// Update the type to the definition's type both here and within the
|
||||
// expression.
|
||||
if (Def) {
|
||||
DRE->setDecl(Def);
|
||||
QualType T = Def->getType();
|
||||
|
|
|
@ -5,3 +5,14 @@ template<bool> struct DominatorTreeBase {
|
|||
};
|
||||
extern template class DominatorTreeBase<false>;
|
||||
constexpr bool k = DominatorTreeBase<false>::IsPostDominator;
|
||||
|
||||
namespace CompleteType {
|
||||
template<unsigned N> constexpr int f(const bool (&)[N]) { return 0; }
|
||||
|
||||
template<bool ...V> struct X {
|
||||
static constexpr bool arr[] = {V...};
|
||||
static constexpr int value = f(arr);
|
||||
};
|
||||
|
||||
constexpr int n = X<true>::value;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue