1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-08 18:26:01 +02:00

Bug 495091 - Name resolution problem with bool() operator

Change-Id: I764c2f6887321f3dee7668550705b517460c152d
This commit is contained in:
Sergey Prigogin 2016-06-07 14:38:50 -07:00
parent 54252787ba
commit 11de0ed6b6
2 changed files with 108 additions and 67 deletions

View file

@ -3209,6 +3209,58 @@ public class AST2TemplateTests extends AST2TestBase {
ba.assertNonProblem("test=", 4, ICPPField.class); ba.assertNonProblem("test=", 4, ICPPField.class);
} }
// template<typename T, typename U>
// struct is_same {};
//
// template<typename T>
// struct is_same<T, T> {
// constexpr operator bool() { return true; }
// };
//
// template<bool>
// struct enable_if {};
//
// template<>
// struct enable_if<true> {
// typedef void type;
// };
//
// template <typename T>
// typename enable_if<is_same<T, T>{}>::type waldo(T p);
//
// void test() {
// waldo(1);
// }
public void testIntegralConversionOperator_495091a() throws Exception {
parseAndCheckBindings();
}
// template<typename T, typename U>
// struct is_same {};
//
// template<typename T>
// struct is_same<T, T> {
// constexpr operator bool() { return true; }
// };
//
// template<bool>
// struct enable_if {};
//
// template<>
// struct enable_if<true> {
// typedef void type;
// };
//
// template <typename T>
// typename enable_if<is_same<T, T>{} && true>::type waldo(T p);
//
// void test() {
// waldo(1);
// }
public void testIntegralConversionOperator_495091b() throws Exception {
parseAndCheckBindings();
}
// class A { // class A {
// public: // public:
// A(const A& a) {} // A(const A& a) {}
@ -7348,10 +7400,10 @@ public class AST2TemplateTests extends AST2TestBase {
public void testTemplateIdNamingAliasTemplateInExpression_472615() throws Exception { public void testTemplateIdNamingAliasTemplateInExpression_472615() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <class> // template <class>
// struct Traits { // struct Traits {
// template <class U> // template <class U>
// using rebind = U; // using rebind = U;
// }; // };
// template <class T> // template <class T>
@ -7945,7 +7997,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testPartialSpecializationForVarargFunctionType_402807() throws Exception { public void testPartialSpecializationForVarargFunctionType_402807() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T> // template <typename T>
// struct waldo { // struct waldo {
// typedef int type; // typedef int type;
@ -7958,23 +8010,23 @@ public class AST2TemplateTests extends AST2TestBase {
public void testPartialSpecializationForRefQualifiedFunctionType_485888() throws Exception { public void testPartialSpecializationForRefQualifiedFunctionType_485888() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<typename T> // template<typename T>
// struct term_traits; // struct term_traits;
// //
// template<typename T> // template<typename T>
// struct term_traits<T const &> { // struct term_traits<T const &> {
// typedef T value_type; // typedef T value_type;
// }; // };
// //
// template<typename T, int N> // template<typename T, int N>
// struct term_traits<T const (&)[N]> { // struct term_traits<T const (&)[N]> {
// typedef T value_type[N]; // typedef T value_type[N];
// }; // };
// //
// using T = const char(&)[4]; // using T = const char(&)[4];
// using ActualType = term_traits<T const &>::value_type; // using ActualType = term_traits<T const &>::value_type;
// //
// using ExpectedType = char[4]; // using ExpectedType = char[4];
public void testQualifierTypeThatCollapsesAfterTypedefSubstitution_487698() throws Exception { public void testQualifierTypeThatCollapsesAfterTypedefSubstitution_487698() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
@ -8133,7 +8185,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testPackExpansionInNestedTemplate_459844() throws Exception { public void testPackExpansionInNestedTemplate_459844() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename T> // template <typename T>
// struct A {}; // struct A {};
// //
@ -8146,21 +8198,21 @@ public class AST2TemplateTests extends AST2TestBase {
IVariable answer = helper.assertNonProblem("answer"); IVariable answer = helper.assertNonProblem("answer");
assertVariableValue(answer, 1); assertVariableValue(answer, 1);
} }
// template <template <class> class ... Mixins> // template <template <class> class ... Mixins>
// struct C : Mixins<int>... {}; // struct C : Mixins<int>... {};
// //
// template <typename> // template <typename>
// struct SpecificMixin {}; // struct SpecificMixin {};
// //
// constexpr bool answer = __is_base_of(SpecificMixin<int>, C<SpecificMixin>); // constexpr bool answer = __is_base_of(SpecificMixin<int>, C<SpecificMixin>);
public void testTemplateTemplateParameterPack_487703a() throws Exception { public void testTemplateTemplateParameterPack_487703a() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
IVariable answer = helper.assertNonProblem("answer"); IVariable answer = helper.assertNonProblem("answer");
assertVariableValue(answer, 1); assertVariableValue(answer, 1);
} }
// template <template <class> class ... Mixins> // template <template <class> class ... Mixins>
// struct C : Mixins<C<Mixins...>>... {}; // struct C : Mixins<C<Mixins...>>... {};
// //
@ -8248,16 +8300,16 @@ public class AST2TemplateTests extends AST2TestBase {
// //
// template <typename T> // template <typename T>
// auto bar(T t) -> decltype(t->foo); // auto bar(T t) -> decltype(t->foo);
// //
// int main() { // int main() {
// S s; // S s;
// auto waldo = bar(&s); // auto waldo = bar(&s);
// } // }
public void testDependentFieldReference_472436a() throws Exception { public void testDependentFieldReference_472436a() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableType("waldo", CommonCPPTypes.int_); helper.assertVariableType("waldo", CommonCPPTypes.int_);
} }
// struct T { // struct T {
// int foo; // int foo;
// }; // };
@ -8267,16 +8319,16 @@ public class AST2TemplateTests extends AST2TestBase {
// //
// template <typename T> // template <typename T>
// auto bar(T t) -> decltype(t->other->foo); // auto bar(T t) -> decltype(t->other->foo);
// //
// int main() { // int main() {
// S s; // S s;
// auto waldo = bar(&s); // auto waldo = bar(&s);
// } // }
public void testDependentFieldReference_472436b() throws Exception { public void testDependentFieldReference_472436b() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
helper.assertVariableType("waldo", CommonCPPTypes.int_); helper.assertVariableType("waldo", CommonCPPTypes.int_);
} }
// template <typename> // template <typename>
// struct Bind {}; // struct Bind {};
// template <typename Func, typename ... BoundArgs> // template <typename Func, typename ... BoundArgs>
@ -8468,7 +8520,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testMemberAccessInPackExpansion_442213() throws Exception { public void testMemberAccessInPackExpansion_442213() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// // Example 1 // // Example 1
// template <typename... T> // template <typename... T>
// void foo1(T&... t) { // void foo1(T&... t) {
@ -8496,7 +8548,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testMemberAccessViaReferenceInPackExpansion_466845() throws Exception { public void testMemberAccessViaReferenceInPackExpansion_466845() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <int... I> // template <int... I>
// struct C {}; // struct C {};
// //
@ -8514,11 +8566,11 @@ public class AST2TemplateTests extends AST2TestBase {
// void test() { // void test() {
// A a; // A a;
// waldo(a, C<>()); // waldo(a, C<>());
// } // }
public void testDecltypeInPackExpansion_486425a() throws Exception { public void testDecltypeInPackExpansion_486425a() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <int... I> // template <int... I>
// struct C {}; // struct C {};
// //
@ -8971,7 +9023,7 @@ public class AST2TemplateTests extends AST2TestBase {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
helper.assertNonProblem("waldo<T>", ICPPDeferredFunction.class); helper.assertNonProblem("waldo<T>", ICPPDeferredFunction.class);
} }
// template<bool, typename T = void> // template<bool, typename T = void>
// struct enable_if {}; // struct enable_if {};
// //
@ -9024,19 +9076,19 @@ public class AST2TemplateTests extends AST2TestBase {
// constexpr bool negate(bool arg) { // constexpr bool negate(bool arg) {
// return !arg; // return !arg;
// } // }
// //
// template <bool B> // template <bool B>
// struct boolean { // struct boolean {
// constexpr operator bool() { return B; } // constexpr operator bool() { return B; }
// }; // };
// //
// constexpr bool waldo = negate(boolean<true>()); // constexpr bool waldo = negate(boolean<true>());
public void testDependentConversionOperator_486426() throws Exception { public void testDependentConversionOperator_486426() throws Exception {
BindingAssertionHelper helper = getAssertionHelper(); BindingAssertionHelper helper = getAssertionHelper();
ICPPVariable waldo = helper.assertNonProblem("waldo"); ICPPVariable waldo = helper.assertNonProblem("waldo");
assertConstantValue(0, waldo); assertConstantValue(0, waldo);
} }
// template <typename> // template <typename>
// struct C { // struct C {
// friend bool operator==(C, C); // friend bool operator==(C, C);
@ -9053,7 +9105,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testStrayFriends_419301() throws Exception { public void testStrayFriends_419301() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename> // template <typename>
// struct A { // struct A {
// struct B { // struct B {
@ -9114,7 +9166,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testConstexprFunctionCallWithNonConstexprArguments_429891() throws Exception { public void testConstexprFunctionCallWithNonConstexprArguments_429891() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename> // template <typename>
// struct S; // struct S;
// //
@ -9266,7 +9318,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testAmbiguityResolutionOrder_462348b() throws Exception { public void testAmbiguityResolutionOrder_462348b() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<typename T> // template<typename T>
// struct remove_reference { // struct remove_reference {
// typedef T type; // typedef T type;
@ -9316,7 +9368,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testAmbiguityResolution_469788() throws Exception { public void testAmbiguityResolution_469788() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename> struct S {}; // template <typename> struct S {};
// struct U {}; // struct U {};
// //
@ -9333,7 +9385,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testAmbiguityResolutionInNestedClassMethodBody_485388() throws Exception { public void testAmbiguityResolutionInNestedClassMethodBody_485388() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<typename T, T v> // template<typename T, T v>
// struct F { // struct F {
// static constexpr T val = v; // static constexpr T val = v;
@ -9369,7 +9421,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testRegression_485388a() throws Exception { public void testRegression_485388a() throws Exception {
parseAndCheckBindings(getAboveComment(), CPP, true); parseAndCheckBindings(getAboveComment(), CPP, true);
} }
// template <typename T> // template <typename T>
// struct A { // struct A {
// void ma(T); // void ma(T);
@ -9392,7 +9444,7 @@ public class AST2TemplateTests extends AST2TestBase {
public void testRegression_485388b() throws Exception { public void testRegression_485388b() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template <typename> // template <typename>
// struct Base { // struct Base {
// template <typename> // template <typename>
@ -9404,7 +9456,7 @@ public class AST2TemplateTests extends AST2TestBase {
// typedef int WALDO; // typedef int WALDO;
// //
// C() { // C() {
// this->template method<WALDO>(0); // this->template method<WALDO>(0);
// } // }
// }; // };
public void testRegression_421823() throws Exception { public void testRegression_421823() throws Exception {
@ -9448,30 +9500,4 @@ public class AST2TemplateTests extends AST2TestBase {
public void testDisambiguationInNoexceptSpecifier_467332() throws Exception { public void testDisambiguationInNoexceptSpecifier_467332() throws Exception {
parseAndCheckBindings(); parseAndCheckBindings();
} }
// template<typename T, typename U>
// struct is_same {};
//
// template<typename T>
// struct is_same<T, T> {
// constexpr operator bool() { return true; }
// };
//
// template<bool>
// struct enable_if {};
//
// template<>
// struct enable_if<true> {
// typedef void type;
// };
//
// template <typename T>
// typename enable_if<is_same<T, T>{}>::type waldo(T p);
//
// void test() {
// waldo(1);
// }
public void testListInitialization_495091() throws Exception {
parseAndCheckBindings();
}
} }

View file

@ -63,6 +63,7 @@ import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPArithmeticConversion;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPImplicitFunction;
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.InstantiationContext; import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
@ -135,15 +136,29 @@ public class EvalBinary extends CPPDependentEvaluation {
@Override @Override
public IValue getValue(IASTNode point) { public IValue getValue(IASTNode point) {
if (getOverload(point) != null) { ICPPEvaluation arg1 = fArg1;
// TODO(sprigogin): Simulate execution of a function call. ICPPEvaluation arg2 = fArg2;
return Value.create(this); ICPPFunction overload = getOverload(point);
if (overload != null) {
ICPPFunctionType functionType = overload.getType();
IType[] parameterTypes = functionType.getParameterTypes();
arg1 = maybeApplyConversion(fArg1, parameterTypes[0], point);
arg2 = maybeApplyConversion(fArg1, parameterTypes[1], point);
if (!(overload instanceof CPPImplicitFunction)) {
if (!overload.isConstexpr())
return Value.ERROR;
ICPPEvaluation eval = new EvalBinding(overload, null, (IBinding) null);
ICPPEvaluation call =
new EvalFunctionCall(new ICPPEvaluation[] {eval, arg1, arg2}, (IBinding) null);
return call.getValue(point);
}
} }
IValue v1 = fArg1.getValue(point); IValue v1 = arg1.getValue(point);
if (v1 == null || v1 == Value.UNKNOWN) if (v1 == null || v1 == Value.UNKNOWN)
return Value.UNKNOWN; return Value.UNKNOWN;
IValue v2 = fArg2.getValue(point); IValue v2 = arg2.getValue(point);
if (v2 == null || v2 == Value.UNKNOWN) if (v2 == null || v2 == Value.UNKNOWN)
return Value.UNKNOWN; return Value.UNKNOWN;