mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 10:16:03 +02:00
Bug 401743 - NullPointerException in EvalBinding.instantiate() - tpMap
is null Change-Id: Iea69ddf7f1872f0e1b0a918faed400b6d5d4f2f7 Reviewed-on: https://git.eclipse.org/r/10641 Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com> IP-Clean: Sergey Prigogin <eclipse.sprigogin@gmail.com> Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
parent
9c4d88dab4
commit
773aa77a2a
4 changed files with 48 additions and 6 deletions
|
@ -7334,4 +7334,29 @@ public class AST2TemplateTests extends AST2TestBase {
|
|||
public void testVariadicNonTypeTemplateParameter_401400() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// template <int...> struct tuple_indices {};
|
||||
// template <int Sp, class IntTuple, int Ep>
|
||||
// struct make_indices_imp;
|
||||
// template <int Sp, int ...Indices, int Ep>
|
||||
// struct make_indices_imp<Sp, tuple_indices<Indices...>, Ep> {
|
||||
// typedef typename make_indices_imp<Sp + 1, tuple_indices<Indices..., Sp>, Ep>::type type;
|
||||
// };
|
||||
// template <int Ep, int ...Indices>
|
||||
// struct make_indices_imp<Ep, tuple_indices<Indices...>, Ep> {
|
||||
// typedef tuple_indices<Indices...> type;
|
||||
// };
|
||||
// template <int Ep, int Sp = 0>
|
||||
// struct make_tuple_indices {
|
||||
// typedef typename make_indices_imp<Sp, tuple_indices<>, Ep>::type type;
|
||||
// };
|
||||
// template <class ... Args>
|
||||
// class async_func {
|
||||
// void operator()() {
|
||||
// typedef typename make_tuple_indices<1 + sizeof...(Args), 1>::type Index;
|
||||
// }
|
||||
// };
|
||||
public void testVariadicTemplatesNPE_401743() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -402,6 +402,18 @@ public class Value implements IValue {
|
|||
public static boolean isDependentValue(IValue nonTypeValue) {
|
||||
if (nonTypeValue == null)
|
||||
return false;
|
||||
// Unknown values may or may not be dependent. In the case of a template with
|
||||
// a non-type template argument, whether or not the argument's value is dependent
|
||||
// determines whether or not the template gets instantiated. In light of this,
|
||||
// it's safer to assume that an unknown value is dependent because:
|
||||
// 1. Instantiating a template with a non-type template argument whose value is
|
||||
// unknown is useless.
|
||||
// 2. Instantiating such a template can lead to an infinite recursion of
|
||||
// instantiations (e.g. consider a template A<N> that delegates to A<N - 1>,
|
||||
// with A<0> being specialized to end the recursion - if N is unknown,
|
||||
// N - 1 will be unknown as well, and we get an infinite recursion).
|
||||
if (nonTypeValue == UNKNOWN)
|
||||
return true;
|
||||
ICPPEvaluation eval = nonTypeValue.getEvaluation();
|
||||
return eval != null && eval.isValueDependent();
|
||||
}
|
||||
|
|
|
@ -279,6 +279,11 @@ public class EvalBinding extends CPPDependentEvaluation {
|
|||
value= ((IVariable) fBinding).getInitialValue();
|
||||
} else if (fBinding instanceof IEnumerator) {
|
||||
value= ((IEnumerator) fBinding).getValue();
|
||||
} else if (fBinding instanceof IFunction) {
|
||||
// If a function passed as a non-type template parameter is constexpr,
|
||||
// it can be used inside the template as a constexpr function, so it's
|
||||
// important to preserve the binding in the value.
|
||||
value = Value.create(this);
|
||||
}
|
||||
if (value == null)
|
||||
value = Value.UNKNOWN;
|
||||
|
@ -336,9 +341,11 @@ public class EvalBinding extends CPPDependentEvaluation {
|
|||
ICPPClassSpecialization within, int maxdepth, IASTNode point) {
|
||||
IBinding origBinding = getBinding();
|
||||
if (origBinding instanceof ICPPTemplateNonTypeParameter) {
|
||||
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) origBinding, packOffset);
|
||||
if (argument != null && argument.isNonTypeValue()) {
|
||||
return argument.getNonTypeEvaluation();
|
||||
if (tpMap != null) {
|
||||
ICPPTemplateArgument argument = tpMap.getArgument((ICPPTemplateNonTypeParameter) origBinding, packOffset);
|
||||
if (argument != null && argument.isNonTypeValue()) {
|
||||
return argument.getNonTypeEvaluation();
|
||||
}
|
||||
}
|
||||
// TODO(sprigogin): Do we need something similar for pack expansion?
|
||||
} else if (origBinding instanceof ICPPParameter) {
|
||||
|
|
|
@ -354,10 +354,8 @@ public class EvalID extends CPPDependentEvaluation {
|
|||
return new EvalFunctionSet(new CPPFunctionSet(functions, templateArgs, null), fAddressOf, getTemplateDefinition());
|
||||
}
|
||||
IBinding binding = bindings.length == 1 ? bindings[0] : null;
|
||||
if (binding instanceof IEnumerator) {
|
||||
if (binding instanceof IEnumerator || binding instanceof ICPPMember) {
|
||||
return new EvalBinding(binding, null, getTemplateDefinition());
|
||||
} else if (binding instanceof ICPPMember) {
|
||||
return new EvalMemberAccess(nameOwner, ValueCategory.PRVALUE, binding, false, getTemplateDefinition());
|
||||
} else if (binding instanceof CPPFunctionSet) {
|
||||
return new EvalFunctionSet((CPPFunctionSet) binding, fAddressOf, getTemplateDefinition());
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue