From 6b1f378dc96c5b46ab63daf2f43ef3ae7e2e50c5 Mon Sep 17 00:00:00 2001 From: Andrew Ferguson Date: Tue, 8 Jan 2008 17:40:26 +0000 Subject: [PATCH] 214335: apply fix and add regression test --- .../core/parser/tests/ast2/AST2BaseTest.java | 56 +++++++++++++++++-- .../core/parser/tests/ast2/AST2CPPTests.java | 51 +++++++++++++++++ .../dom/parser/cpp/CPPASTTranslationUnit.java | 2 +- .../core/dom/parser/cpp/CPPSemantics.java | 21 +++++-- 4 files changed, 121 insertions(+), 9 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index 6a3cd418f1f..b26510b25c6 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -17,7 +17,9 @@ package org.eclipse.cdt.core.parser.tests.ast2; import java.io.IOException; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.ListIterator; import org.eclipse.cdt.core.dom.ast.ASTSignatureUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; @@ -46,6 +48,8 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.c.CASTVisitor; import org.eclipse.cdt.core.dom.ast.c.ICASTTypeIdInitializerExpression; import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor; +import org.eclipse.cdt.core.dom.ast.gnu.c.GCCLanguage; +import org.eclipse.cdt.core.dom.ast.gnu.cpp.GPPLanguage; import org.eclipse.cdt.core.dom.parser.IScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.ISourceCodeParser; import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration; @@ -56,6 +60,7 @@ import org.eclipse.cdt.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.GPPScannerExtensionConfiguration; import org.eclipse.cdt.core.dom.parser.cpp.ICPPParserExtensionConfiguration; +import org.eclipse.cdt.core.model.ILanguage; import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.IParserLogService; import org.eclipse.cdt.core.parser.IScanner; @@ -90,11 +95,11 @@ public class AST2BaseTest extends BaseTestCase { super(name); } - protected IASTTranslationUnit parse( String code, ParserLanguage lang ) throws ParserException { + static protected IASTTranslationUnit parse( String code, ParserLanguage lang ) throws ParserException { return parse(code, lang, false, true ); } - protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions ) throws ParserException { + static protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions ) throws ParserException { return parse( code, lang, useGNUExtensions, true ); } /** @@ -103,11 +108,11 @@ public class AST2BaseTest extends BaseTestCase { * @return * @throws ParserException */ - protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException{ + static protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems ) throws ParserException{ return parse(code, lang, useGNUExtensions, expectNoProblems, false); } - protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems , boolean parseComments) throws ParserException { + static protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions, boolean expectNoProblems , boolean parseComments) throws ParserException { IScanner scanner = createScanner(new CodeReader(code.toCharArray()), lang, ParserMode.COMPLETE_PARSE, new ScannerInfo(), parseComments); ISourceCodeParser parser2 = null; @@ -413,4 +418,47 @@ public class AST2BaseTest extends BaseTestCase { ICompositeType struct = ((IField) binding).getCompositeTypeOwner(); assertEquals(ownerName, struct.getName()); } + + static protected class BindingAssertionHelper { + protected IASTTranslationUnit tu; + protected String contents; + protected boolean isCPP; + + public BindingAssertionHelper(String contents, boolean isCPP) throws ParserException { + this.contents= contents; + this.isCPP= isCPP; + this.tu= parse(contents, isCPP ? ParserLanguage.CPP : ParserLanguage.C, true, false ); + } + + public IBinding assertProblem(String section, int len) { + IBinding binding= binding(section, len); + assertTrue("Binding is not a ProblemBinding for name: "+section, binding instanceof IProblemBinding); + return binding; + } + + public IBinding assertNonProblem(String section, int len) { + IBinding binding= binding(section, len); + assertTrue("Binding is a ProblemBinding for name: "+section, !(binding instanceof IProblemBinding)); + return binding; + } + + private IBinding binding(String section, int len) { + ILanguage language = isCPP ? GPPLanguage.getDefault() : GCCLanguage.getDefault(); + IASTName[] names= language.getSelectedNames(tu, contents.indexOf(section), len); + List lnames= new ArrayList(Arrays.asList(names)); + for(ListIterator li= lnames.listIterator(); li.hasNext(); ) { + IASTName name= (IASTName) li.next(); + if(name.getRawSignature().length()!=len) { + li.remove(); + } + } + names= (IASTName[]) lnames.toArray(new IASTName[lnames.size()]); + assertEquals("<>1 name found for \""+section+"\"", 1, names.length); + + IBinding binding = names[0].resolveBinding(); + assertNotNull("No binding for "+names[0].getRawSignature(), binding); + + return names[0].resolveBinding(); + } + } } 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 e0c3bbb930a..e8fac54c7d3 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 @@ -5527,4 +5527,55 @@ public class AST2CPPTests extends AST2BaseTest { buffer.append( "void zot (void *p) throw () __attribute__ (( __nonnull__(1) )); \n"); //$NON-NLS-1$ parse( buffer.toString(), ParserLanguage.CPP, true, true ); } + + // class C { + // public: + // int i; + // }; + // + // void problem1(int x) {} + // void problem2(const int *x) {} + // void problem3(int* x) {} + // + // void nonproblem1(bool x) {} + // void problem4(bool* x) {} + // void problem5(const bool* x) {} + // + // void f() { + // int C::* ptm; + // + // problem1("p"); + // problem2("p"); + // problem3("p"); + // nonproblem1("p"); + // problem4("p"); + // problem5("p"); + // + // problem1(ptm); + // problem2(ptm); + // problem3(ptm); + // nonproblem1(ptm); + // problem4(ptm); + // problem5(ptm); + // } + public void testBug214335() throws Exception { + BindingAssertionHelper bh= new BindingAssertionHelper(getContents(1)[0].toString(), true); + + IBinding b00= bh.assertProblem("problem1(\"", 8); + IBinding b01= bh.assertProblem("problem2(\"", 8); + IBinding b02= bh.assertProblem("problem3(\"", 8); + IBinding b03= bh.assertNonProblem("nonproblem1(\"", 11); + IBinding b04= bh.assertProblem("problem4(\"", 8); + IBinding b05= bh.assertProblem("problem5(\"", 8); + + IBinding b06= bh.assertProblem("problem1(ptm", 8); + IBinding b07= bh.assertProblem("problem2(ptm", 8); + IBinding b08= bh.assertProblem("problem3(ptm", 8); + IBinding b09= bh.assertNonProblem("nonproblem1(ptm", 11); + IBinding b10= bh.assertProblem("problem4(ptm", 8); + IBinding b11= bh.assertProblem("problem5(ptm", 8); + + assertInstance(b03, ICPPFunction.class); + assertInstance(b09, ICPPFunction.class); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java index a7d875def6e..247e1714c3c 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTranslationUnit.java @@ -143,7 +143,7 @@ public class CPPASTTranslationUnit extends CPPASTNode implements ICPPASTTranslat // void operator delete(void*); temp = null; IType[] deleteParms = new IType[1]; - deleteParms[0] = cpp_size_t; + deleteParms[0] = cpp_void_p; IFunctionType deleteFunctionType = new CPPFunctionType(cpp_void, deleteParms); IParameter[] deleteTheParms = new IParameter[1]; deleteTheParms[0] = new CPPBuiltinParameter(deleteParms[0]); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index f45c9f0eb70..1a1d70ac5ad 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -3019,6 +3019,14 @@ public class CPPSemantics { if( op1 == null && op2 == null ) break; else if( op1 == null ^ op2 == null) { + // 4.12 - pointer types can be converted to bool + if(t instanceof ICPPBasicType) { + if(((ICPPBasicType)t).getType() == ICPPBasicType.t_bool) { + canConvert= true; + requiredConversion = Cost.CONVERSION_RANK; + break; + } + } canConvert = false; break; } else if( op1 instanceof ICPPPointerToMemberType ^ op2 instanceof ICPPPointerToMemberType ){ @@ -3129,8 +3137,8 @@ public class CPPSemantics { * @throws DOMException */ static private void promotion( Cost cost ) throws DOMException{ - IType src = getUltimateType( cost.source, true ); - IType trg = getUltimateType( cost.target, true ); + IType src = cost.source; + IType trg = cost.target; if( src.isSameType( trg ) ) return; @@ -3203,13 +3211,18 @@ public class CPPSemantics { cost.detail= 1; return; } - } + // 4.12 if the target is a bool, we can still convert + else if(!(trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool)) { + return; + } + } + if( t instanceof IBasicType && s instanceof IBasicType || s instanceof IEnumeration ){ //4.7 An rvalue of an integer type can be converted to an rvalue of another integer type. //An rvalue of an enumeration type can be converted to an rvalue of an integer type. cost.rank = Cost.CONVERSION_RANK; cost.conversion = 1; - } else if( t instanceof IBasicType && ((IBasicType)t).getType() == ICPPBasicType.t_bool && s instanceof IPointerType ){ + } else if( trg instanceof IBasicType && ((IBasicType)trg).getType() == ICPPBasicType.t_bool && s instanceof IPointerType ){ //4.12 pointer or pointer to member type can be converted to an rvalue of type bool cost.rank = Cost.CONVERSION_RANK; cost.conversion = 1;