From ae3a0adb81e1e6e77a9c76a50ff7bc73f3d90b41 Mon Sep 17 00:00:00 2001 From: "Igor V. Kovalenko" Date: Thu, 9 Mar 2023 02:26:08 +0300 Subject: [PATCH] More tests for list-initialization of class or aggregate --- .../tests/ast2/AST2CPPImplicitNameTests.java | 6 +- .../core/parser/tests/ast2/AST2CPPTests.java | 74 ++++++++++++++++++- 2 files changed, 76 insertions(+), 4 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java index 3f3b11961a8..eb2eb4fb699 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPImplicitNameTests.java @@ -576,10 +576,12 @@ public class AST2CPPImplicitNameTests extends AST2TestBase { ba.assertNoImplicitName("e;", 1); IASTImplicitName s = ba.assertImplicitName("s =", 1, ICPPConstructor.class); assertSame(ctor1, s.resolveBinding()); - ba.assertNoImplicitName("t;", 1); + IASTImplicitName t_static = ba.assertImplicitName("t;", 1, ICPPConstructor.class); + assertSame(ctor0, t_static.resolveBinding()); IASTImplicitName t = ba.assertImplicitName("t =", 1, ICPPConstructor.class); assertSame(ctor1, t.resolveBinding()); - ba.assertNoImplicitName("u;", 1); + IASTImplicitName u_member = ba.assertImplicitName("u;", 1, ICPPConstructor.class); + assertSame(ctor0, u_member.resolveBinding()); IASTImplicitName u = ba.assertImplicitName("u()", 1, ICPPConstructor.class); assertSame(ctor0, u.resolveBinding()); IASTImplicitName v = ba.assertImplicitName("v(p)", 1, ICPPConstructor.class); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index ced3e72e681..23bbea037b6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -8848,7 +8848,7 @@ public class AST2CPPTests extends AST2CPPTestBase { // h({ "foo" }); // OK: h(C(std::string("foo"))) // i({ { 1, 2 }, { "bar" } }); // OK: i(D(A(std::initializer_list{1,2}),C(std::string("bar")))) // X x1; - // x({x1}); // no matching constructor + // x({x1}); // OK, lvalue reference to x1 // } public void testListInitialization_302412c() throws Exception { String code = getAboveComment(); @@ -8859,7 +8859,7 @@ public class AST2CPPTests extends AST2CPPTestBase { bh.assertProblem("f({ 'a', 'b' })", 1); bh.assertNonProblem("h({", 1); bh.assertNonProblem("i({ { 1, 2 }, {", 1); - bh.assertProblem("x({x1})", 1); + bh.assertNonProblem("x({x1})", 1); } // namespace std { @@ -9073,6 +9073,76 @@ public class AST2CPPTests extends AST2CPPTestBase { parseAndCheckBindings(); } + // namespace std { + // template class initializer_list; + // } + // struct str { + // str(); + // str(const char*, int); // #1 + // str(std::initializer_list); // #2 + // }; + // struct subclass : public str { + // }; + // void g1(str); + // void g2(str); + // void test() { + // const str a{"test", 4}; // OK, #2 fails, uses #1 to initialize + // const subclass s; + // g1({a}); + // g2({s}); + // } + public void testListInitializationOfClass() throws Exception { + parseAndCheckImplicitNameBindings(); + } + + // namespace std { + // template class initializer_list; + // } + // struct str { + // str(); + // explicit str(const char*, int); // #1 + // str(std::initializer_list); // #2 + // }; + // + // str test(char *p, int i) { + // const str a{"test", 4}; // OK, #2 fails, uses #1 to initialize + // const str b = {"test", 4}; // ERROR, #2 fails, #1 is skipped explicit conversion + // return str{p, i}; // OK, uses #1 to initialize, explicit constructor is considered too + // } + public void testListInitializationWithExplicitConstructor() throws Exception { + IASTTranslationUnit tu = parse(getAboveComment(), CPP); + NameCollector collector = new NameCollector(true); + tu.accept(collector); + + assertEquals(28, collector.size()); + // 23th is implicit name for constructor for b + IASTImplicitName nameOfConstructorForB = (IASTImplicitName) collector.getName(23); + IProblemBinding problemConstructorForB = (IProblemBinding) nameOfConstructorForB.resolveBinding(); + assertEquals(problemConstructorForB.getID(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND); + + // 25th is implicit name for constructor of object in return statement + IASTImplicitName nameOfConstructorForReturn = (IASTImplicitName) collector.getName(25); + ICPPConstructor constructorOfReturn = (ICPPConstructor) nameOfConstructorForReturn.resolveBinding(); + } + + // namespace std { + // template class initializer_list; + // } + // struct str { + // str(); + // str(const char*, int); // #1 + // str(std::initializer_list); // #2 + // }; + // + // str test(char *p, int i) { + // const str a{"test", 4}; // OK, #2 fails, uses #1 to initialize + // const str b = {"test", 4}; // OK, #2 fails, uses #1 to initialize + // return str{p, i}; // OK, uses #1 to initialize + // } + public void testListInitializationOfClassTypeId() throws Exception { + parseAndCheckImplicitNameBindings(); + } + // namespace std { // template class initializer_list; // }