From 0408d6e90179a6ecb1fba55077db24cdcec89da7 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Fri, 14 Dec 2007 15:58:14 +0000 Subject: [PATCH] Fix cv-conversion, bug 213029. --- .../cdt/core/parser/tests/ast2/AST2Tests.java | 27 +++++++++++++++++++ .../core/dom/parser/cpp/CPPSemantics.java | 23 +++++++++++----- 2 files changed, 44 insertions(+), 6 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index e8cfb5e9511..32786646cc5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -4168,4 +4168,31 @@ public class AST2Tests extends AST2BaseTest { StringBuffer buffer = getContents(1)[0]; parseAndCheckBindings(buffer.toString(), ParserLanguage.CPP); } + + // int* i= 0; + // void f1(const int**); + // void f2(int *const*); + // void f3(const int *const*); + // + // void test() { + // f1(&i); // forbidden + // f2(&i); // ok + // f3(&i); // ok + // } + public void testBug213029_cvConversion() throws Exception { + StringBuffer buffer = getContents(1)[0]; + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP, false ); + CNameCollector col = new CNameCollector(); + tu.accept(col); + Iterator i = col.nameList.iterator(); + while (i.hasNext()) { + IASTName n = (IASTName) i.next(); + if (n.isReference() && "f1".equals(n.toString())) { + assertTrue(n.resolveBinding() instanceof IProblemBinding); + } + else { + assertFalse(n.resolveBinding() instanceof IProblemBinding); + } + } + } } \ No newline at end of file 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 1f5fc6c406c..f45c9f0eb70 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 @@ -3009,6 +3009,7 @@ public class CPPSemantics { IType s = cost.source, t = cost.target; boolean constInEveryCV2k = true; + boolean firstPointer= true; while( true ){ s= getUltimateTypeViaTypedefs(s); t= getUltimateTypeViaTypedefs(t); @@ -3039,15 +3040,22 @@ public class CPPSemantics { requiredConversion = Cost.NO_MATCH_RANK; break; } - constInEveryCV2k &= op2.isConst(); + constInEveryCV2k &= (firstPointer || op2.isConst()); s = op1.getType(); t = op2.getType(); + firstPointer= false; } if( s instanceof IQualifierType ^ t instanceof IQualifierType ){ if( t instanceof IQualifierType ){ - canConvert = true; - requiredConversion = Cost.CONVERSION_RANK; + if (!constInEveryCV2k) { + canConvert= false; + requiredConversion= Cost.NO_MATCH_RANK; + } + else { + canConvert = true; + requiredConversion = Cost.CONVERSION_RANK; + } } else { //4.2-2 a string literal can be converted to pointer to char if( t instanceof IBasicType && ((IBasicType)t).getType() == IBasicType.t_char && @@ -3070,10 +3078,13 @@ public class CPPSemantics { } } else if( s instanceof IQualifierType && t instanceof IQualifierType ){ IQualifierType qs = (IQualifierType) s, qt = (IQualifierType) t; - if( qs.isConst() && !qt.isConst() || qs.isVolatile() && !qt.isVolatile() ) - requiredConversion = Cost.NO_MATCH_RANK; - else if( qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile() ) + if( qs.isConst() == qt.isConst() && qs.isVolatile() == qt.isVolatile() ) { requiredConversion = Cost.IDENTITY_RANK; + } + else if( (qs.isConst() && !qt.isConst()) || (qs.isVolatile() && !qt.isVolatile()) || !constInEveryCV2k ) { + requiredConversion = Cost.NO_MATCH_RANK; + canConvert= false; + } else requiredConversion = Cost.CONVERSION_RANK; } else if( constInEveryCV2k && !canConvert ){