1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-22 06:02:11 +02:00

Actually apply type conversion in CPPEvaluation maybeApplyConversion()

Currently type of parameters of instantiated template function is ignored while
preparing activation record, which makes constexpr evaluation of instantiated
body use types of arguments in function call expression instead:

    template<typename T> bool f(T t) { return t > 0; }
    t<unsigned int>(-1); // CDT returns false because conversion is not done

Fix this by applying EvalTypeId to argument if cost of standard conversions is
Rank.CONVERSION to make sure createActivationRecord() would populate activation
record with argument values matching template parameter types.
This commit is contained in:
Igor V. Kovalenko 2023-02-12 00:51:11 +03:00 committed by Jonah Graham
parent beb201e082
commit 09ab420f17

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2012, 2014 Google, Inc and others. * Copyright (c) 2012, 2014, 2023 Google, Inc and others.
* *
* This program and the accompanying materials * This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0 * are made available under the terms of the Eclipse Public License 2.0
@ -11,6 +11,7 @@
* Contributors: * Contributors:
* Sergey Prigogin (Google) - initial API and implementation * Sergey Prigogin (Google) - initial API and implementation
* Nathan Ridge * Nathan Ridge
* Igor V. Kovalenko
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@ -34,6 +35,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.Context;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Conversions.UDCMode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.Rank;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
public abstract class CPPEvaluation implements ICPPEvaluation { public abstract class CPPEvaluation implements ICPPEvaluation {
@ -207,9 +209,12 @@ public abstract class CPPEvaluation implements ICPPEvaluation {
// Source type is not a class type, or is but a conversion operator wasn't used. // Source type is not a class type, or is but a conversion operator wasn't used.
// Check for standard conversions. // Check for standard conversions.
if (!Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN, Cost cost = Conversions.checkImplicitConversionSequence(targetType, type, valueCategory, UDCMode.FORBIDDEN,
Context.ORDINARY).converts()) { Context.ORDINARY);
if (!cost.converts()) {
return EvalFixed.INCOMPLETE; return EvalFixed.INCOMPLETE;
} else if (cost.getRank() == Rank.CONVERSION) {
return new EvalTypeId(targetType, argument.getTemplateDefinition(), false, false, argument);
} }
} catch (DOMException e) { } catch (DOMException e) {
CCorePlugin.log(e); CCorePlugin.log(e);