1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 10:16:03 +02:00

Bug 415198 - [false positive] Semantic error for decltype(func())::name

in dependent context

Change-Id: I12d41dd88fb5fd5e501907bc709efdabc44f3d17
Signed-off-by: Nathan Ridge <zeratul976@hotmail.com>
Reviewed-on: https://git.eclipse.org/r/15569
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:
Nathan Ridge 2013-08-18 03:12:10 -04:00 committed by Sergey Prigogin
parent e9d295e1a6
commit 68a9017f2e
3 changed files with 50 additions and 19 deletions

View file

@ -8039,4 +8039,25 @@ public class AST2TemplateTests extends AST2TestBase {
public void testOutOfLineMethodOfPartialSpecialization_401152() throws Exception { public void testOutOfLineMethodOfPartialSpecialization_401152() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T>
// T foo(T);
//
// template <typename T>
// struct U {
// typedef typename decltype(foo(T()))::type type;
// };
//
// struct S {
// typedef int type;
// };
//
// int main() {
// U<S>::type x;
// }
public void testDependentDecltypeInNameQualifier_415198() throws Exception {
BindingAssertionHelper helper = getAssertionHelper();
helper.assertNonProblem("decltype(foo(T()))::type");
assertSameType((ITypedef) helper.assertNonProblem("U<S>::type"), CommonTypes.int_);
}
} }

View file

@ -1266,12 +1266,19 @@ public class CPPTemplates {
} }
if (type instanceof ICPPUnknownBinding) { if (type instanceof ICPPUnknownBinding) {
if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation eval = ((TypeOfDependentExpression) type).getEvaluation();
ICPPEvaluation instantiated = eval.instantiate(tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
if (instantiated != eval)
return instantiated.getTypeOrFunctionSet(point);
} else {
IBinding binding= resolveUnknown((ICPPUnknownBinding) type, tpMap, packOffset, within, point); IBinding binding= resolveUnknown((ICPPUnknownBinding) type, tpMap, packOffset, within, point);
if (binding instanceof IType) if (binding instanceof IType)
return (IType) binding; return (IType) binding;
return type; return type;
} }
}
if (within != null && type instanceof IBinding) { if (within != null && type instanceof IBinding) {
IType unwound= getNestedType(type, TDEF); IType unwound= getNestedType(type, TDEF);
@ -1348,13 +1355,6 @@ public class CPPTemplates {
return typeContainer; return typeContainer;
} }
if (type instanceof TypeOfDependentExpression) {
ICPPEvaluation eval = ((TypeOfDependentExpression) type).getEvaluation();
ICPPEvaluation instantiated = eval.instantiate(tpMap, packOffset, within, Value.MAX_RECURSION_DEPTH, point);
if (instantiated != eval)
return instantiated.getTypeOrFunctionSet(point);
}
return type; return type;
} catch (DOMException e) { } catch (DOMException e) {
return e.getProblem(); return e.getProblem();
@ -2646,6 +2646,11 @@ public class CPPTemplates {
if (type instanceof IBinding) if (type instanceof IBinding)
return (IBinding) type; return (IBinding) type;
} }
if (unknown instanceof TypeOfDependentExpression) {
IType type= instantiateType((IType) unknown, tpMap, packOffset, within, point);
if (type instanceof IBinding)
return (IBinding) type;
}
return unknown; return unknown;
} }

View file

@ -12,11 +12,13 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation; import org.eclipse.cdt.internal.core.dom.parser.ISerializableEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.ISerializableType; import org.eclipse.cdt.internal.core.dom.parser.ISerializableType;
import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer; import org.eclipse.cdt.internal.core.dom.parser.ITypeMarshalBuffer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType; import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPEvaluation;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -24,10 +26,11 @@ import org.eclipse.core.runtime.CoreException;
/** /**
* Represents the type of a dependent expression. * Represents the type of a dependent expression.
*/ */
public class TypeOfDependentExpression implements ICPPUnknownType, ISerializableType { public class TypeOfDependentExpression extends CPPUnknownBinding implements ICPPUnknownType, ISerializableType {
private final ICPPEvaluation fEvaluation; private final ICPPEvaluation fEvaluation;
public TypeOfDependentExpression(ICPPEvaluation evaluation) { public TypeOfDependentExpression(ICPPEvaluation evaluation) {
super(evaluation.getSignature());
fEvaluation= evaluation; fEvaluation= evaluation;
} }
@ -42,12 +45,8 @@ public class TypeOfDependentExpression implements ICPPUnknownType, ISerializable
} }
@Override @Override
public Object clone() { public TypeOfDependentExpression clone() {
try { return (TypeOfDependentExpression) super.clone();
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
} }
public char[] getSignature() { public char[] getSignature() {
@ -73,4 +72,10 @@ public class TypeOfDependentExpression implements ICPPUnknownType, ISerializable
return new TypeOfDependentExpression((ICPPEvaluation) eval); return new TypeOfDependentExpression((ICPPEvaluation) eval);
return ProblemType.UNKNOWN_FOR_EXPRESSION; return ProblemType.UNKNOWN_FOR_EXPRESSION;
} }
@Override
public IBinding getOwner() {
// We won't know until instantiation.
return null;
}
} }