diff options
author | Hansruedi Patzen | 2017-11-21 14:51:19 +0000 |
---|---|---|
committer | Nathan Ridge | 2017-11-30 19:56:02 +0000 |
commit | a4dcbbaf1519cc06676a6c3355a4c594407efd0a (patch) | |
tree | 90627cc48e058f184e11d2062cfd4c5d8c3c3fe2 /core | |
parent | 89d45ef7fd160418d0bbb54fb4488748d6db235d (diff) | |
download | org.eclipse.cdt-a4dcbbaf1519cc06676a6c3355a4c594407efd0a.tar.gz org.eclipse.cdt-a4dcbbaf1519cc06676a6c3355a4c594407efd0a.tar.xz org.eclipse.cdt-a4dcbbaf1519cc06676a6c3355a4c594407efd0a.zip |
Bug 527553: Detect invalid decltype(auto) with a type specifier
The evaluated type of 'decltype(auto)' in combination with const and/or
volatile will be a ProblemType since this is not valid code. The patch
also contains a checker to give the user a visual feedback.
Note: A proposed quick-fix has been removed after a short discussion.
Change-Id: I8760ed0ac28e28529ab30516accac9c0413c87d9
Signed-off-by: Hansruedi Patzen <hansruedi.patzen@hsr.ch>
Diffstat (limited to 'core')
2 files changed, 59 insertions, 0 deletions
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 1d1537171f7..dca395e394c 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 @@ -12268,6 +12268,9 @@ public class AST2CPPTests extends AST2CPPTestBase { // decltype(auto) j{42}; // Valid since C++17: decltype(j) is int // decltype(auto) k = new decltype(auto)(1L); // decltype(j) is long int * // decltype(auto) l; // Error - missing initializer. + // decltype(auto) const m = 42; // Error - decltype(auto) does not allow type specifiers. Bug 527553 + // decltype(auto) volatile n = 42; // Error - decltype(auto) does not allow type specifiers. Bug 527553 + // decltype(auto) const volatile o = 42; // Error - decltype(auto) does not allow type specifiers. Bug 527553 public void testDecltypeAutoVariableTypes_482225() throws Exception { String code = getAboveComment(); BindingAssertionHelper bh = new AST2AssertionHelper(code, true); @@ -12306,6 +12309,54 @@ public class AST2CPPTests extends AST2CPPTestBase { ICPPVariable l = bh.assertNonProblem("l;", 1); IProblemType lType = (IProblemType) l.getType(); assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE, lType.getID()); + + ICPPVariable m = bh.assertNonProblem("m =", 1); + IProblemType mType = (IProblemType) m.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE, mType.getID()); + + ICPPVariable n = bh.assertNonProblem("n =", 1); + IProblemType nType = (IProblemType) n.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE, nType.getID()); + + ICPPVariable o = bh.assertNonProblem("o =", 1); + IProblemType oType = (IProblemType) o.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE, oType.getID()); + } + + // auto foo() -> decltype(auto) const { + // return 23.0; + // } + // auto a = foo(); + public void testDecltypeAutoTrailingReturnTypeConst_527553() throws Exception { + String code = getAboveComment(); + BindingAssertionHelper bh = new AST2AssertionHelper(code, true); + ICPPVariable a = bh.assertNonProblem("a =", 1); + IProblemType aType = (IProblemType) a.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, aType.getID()); + } + + // auto foo() -> decltype(auto) volatile { + // return 23.0; + // } + // auto a = foo(); + public void testDecltypeAutoTrailingReturnTypeVolatile_527553() throws Exception { + String code = getAboveComment(); + BindingAssertionHelper bh = new AST2AssertionHelper(code, true); + ICPPVariable a = bh.assertNonProblem("a =", 1); + IProblemType aType = (IProblemType) a.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_AUTO_TYPE, aType.getID()); + } + + // auto foo() -> decltype(auto) const { + // return 23.0; + // } + // decltype(auto) a = foo(); + public void testDecltypeAutoTrailingReturnTypeConstDecltype_527553() throws Exception { + String code = getAboveComment(); + BindingAssertionHelper bh = new AST2AssertionHelper(code, true); + ICPPVariable a = bh.assertNonProblem("a =", 1); + IProblemType aType = (IProblemType) a.getType(); + assertEquals(ISemanticProblem.TYPE_CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE, aType.getID()); } // auto foo() -> decltype(auto) { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java index c24d6402b15..4ccbc5f2741 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java @@ -2270,6 +2270,10 @@ public class CPPVisitor extends ASTQueries { // 'decltype(auto)' cannot be combined with * or & the way 'auto' can. return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE; } + if (declSpec.isConst() || declSpec.isVolatile()) { + // 'decltype(auto)' cannot be combined with any type specifiers. [dcl.type.auto.deduct] + return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE; + } if (autoInitClause instanceof IASTExpression) { return getDeclType((IASTExpression) autoInitClause); } else { @@ -2392,6 +2396,10 @@ public class CPPVisitor extends ASTQueries { // 'decltype(auto)' cannot be combined with * or & the way 'auto' can. return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE; } + if (autoDeclSpec.isConst() || autoDeclSpec.isVolatile()) { + // 'decltype(auto)' cannot be combined with any type specifiers. [dcl.type.auto.deduct] + return ProblemType.CANNOT_DEDUCE_DECLTYPE_AUTO_TYPE; + } return CPPSemantics.getDeclTypeForEvaluation(returnEval); } else /* auto */ { return createAutoType(returnEval, autoDeclSpec, autoDeclarator); |