1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

214335: apply fix and add regression test

This commit is contained in:
Andrew Ferguson 2008-01-08 17:40:26 +00:00
parent 3c10d0917e
commit 6b1f378dc9
4 changed files with 121 additions and 9 deletions

View file

@ -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();
}
}
}

View file

@ -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);
}
}

View file

@ -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]);

View file

@ -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;