From 1ea19101fffa0937e3524fffd4eed5b2b486b26b Mon Sep 17 00:00:00 2001 From: Nathan Ridge Date: Wed, 10 Dec 2014 02:02:31 -0500 Subject: [PATCH] Bug 451091 - Make type of constexpr variable const-qualified Change-Id: I2744ba8dbf2b629659f778d257b1d22483eb6c33 Signed-off-by: Nathan Ridge Reviewed-on: https://git.eclipse.org/r/37929 Reviewed-by: Sergey Prigogin Tested-by: Sergey Prigogin --- .../core/parser/tests/ast2/AST2CPPTests.java | 29 +++++++++++++++++++ .../core/parser/tests/ast2/AST2TestBase.java | 2 ++ .../dom/parser/cpp/semantics/CPPVisitor.java | 16 +++++++++- 3 files changed, 46 insertions(+), 1 deletion(-) 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 4e05e2cf07c..5471341e960 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 @@ -141,7 +141,9 @@ import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPMethod; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding; import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator; @@ -10978,4 +10980,31 @@ public class AST2CPPTests extends AST2TestBase { IASTSimpleDeclaration sd = (IASTSimpleDeclaration) tu.getDeclarations()[0]; isParameterSignatureEqual(sd.getDeclarators()[0], "(int&&)"); } + + // constexpr int waldo1 = 42; + // constexpr auto waldo2 = 43; + public void testConstexprVariableIsConst_451091() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + ICPPVariable waldo1 = helper.assertNonProblem("waldo1"); + ICPPVariable waldo2 = helper.assertNonProblem("waldo2"); + // constexpr on a variable *should* make it const + assertSameType(waldo1.getType(), CommonTypes.constInt); + assertSameType(waldo2.getType(), CommonTypes.constInt); + } + + // constexpr int waldo1(); + // constexpr int (*waldo2())(int); + // struct S { constexpr int waldo3(); }; + public void testTypeOfConstexprFunction_451090() throws Exception { + BindingAssertionHelper helper = getAssertionHelper(); + ICPPFunction waldo1 = helper.assertNonProblem("waldo1"); + ICPPFunction waldo2 = helper.assertNonProblem("waldo2"); + ICPPFunction waldo3 = helper.assertNonProblem("waldo3"); + // constexpr on a function *should not* make its return type const + assertSameType(waldo1.getType().getReturnType(), CommonTypes.int_); + assertSameType(waldo2.getType().getReturnType(), + new CPPPointerType(new CPPFunctionType(CommonTypes.int_, new IType[]{ CommonTypes.int_ }))); + // constexpr on a method *should not* make the method const + assertSameType(waldo3.getType(), new CPPFunctionType(CommonTypes.int_, new IType[]{})); + } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java index e255cb12115..883355c4071 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TestBase.java @@ -91,6 +91,7 @@ import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPPointerType; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPQualifierType; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.model.ASTStringUtil; @@ -108,6 +109,7 @@ public class AST2TestBase extends BaseTestCase { protected static class CommonTypes { public static IType int_ = new CPPBasicType(Kind.eInt, 0); public static IType pointerToInt = new CPPPointerType(int_); + public static IType constInt = new CPPQualifierType(int_, true, false); } private static final ScannerInfo GNU_SCANNER_INFO = new ScannerInfo(getGnuMap()); 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 8c64db5ec4f..8e39fe55b17 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 @@ -2032,8 +2032,9 @@ public class CPPVisitor extends ASTQueries { } IType type = createType(declSpec); + type = makeConstIfConstexpr(type, declSpec, declarator); type = createType(type, declarator); - + // C++ specification 8.3.4.3 and 8.5.1.4 IASTNode initClause= declarator.getInitializer(); if (initClause instanceof IASTEqualsInitializer) { @@ -2236,9 +2237,22 @@ public class CPPVisitor extends ASTQueries { private static IType decorateType(IType type, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { type = qualifyType(type, declSpec); + type = makeConstIfConstexpr(type, declSpec, declarator); return createType(type, declarator); } + private static IType makeConstIfConstexpr(IType type, IASTDeclSpecifier declSpec, IASTDeclarator declarator) { + // [dcl.constexpr] p9: constexpr on a variable makes it const + if (!(declarator instanceof IASTFunctionDeclarator)) { + if (declSpec instanceof ICPPASTDeclSpecifier) { + if (((ICPPASTDeclSpecifier) declSpec).isConstexpr()) { + return SemanticUtil.constQualify(type); + } + } + } + return type; + } + private static IType qualifyType(IType type, IASTDeclSpecifier declSpec) { return SemanticUtil.addQualifiers(type, declSpec.isConst(), declSpec.isVolatile(), declSpec.isRestrict()); }