[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[cdt-patch] [FIXED][77821]usualArithmeticConversions doesn't handle pointers
|
[FIXED][77821] usualArithmeticConversions
doesn't handle pointers
I've added better detection of 'invalid
arithmetic conversions'. All of the corresponding IProblems go away.
There are still a couple flaky 'invalid arithmetic conversion' IProblems
that exist but they are now caused by other bugs which need to be discovered
and raised. One such bug has already been raised (but doesn't have
the corresponding IProblem that depends on it):
https://bugs.eclipse.org/bugs/show_bug.cgi?id=78798
Devin Steffler
IBM's Eclipse CDT
Ottawa (Palladium), Ontario, Canada
Index: CompleteParseASTTest.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java,v
retrieving revision 1.134
diff -u -r1.134 CompleteParseASTTest.java
--- CompleteParseASTTest.java 15 Nov 2004 22:17:29 -0000 1.134
+++ CompleteParseASTTest.java 18 Nov 2004 14:04:57 -0000
@@ -2332,5 +2332,14 @@
writer.write("#endif\n"); //$NON-NLS-1$
parse(writer.toString());
}
+
+ public void testBug77821() throws Exception {
+ Writer writer = new StringWriter();
+ writer.write("typedef struct { /* ... */ }TYPE;\n"); //$NON-NLS-1$
+ writer.write("void ptrArith(const TYPE* pType) {\n"); //$NON-NLS-1$
+ writer.write("TYPE *temp = 0;\n"); //$NON-NLS-1$
+ writer.write("temp = (TYPE*)(pType + 1); /* Parser error is here */\n}\n"); //$NON-NLS-1$
+ parse(writer.toString());
+ }
}
Index: CompleteParseASTFactory.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt-core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java,v
retrieving revision 1.197
diff -u -r1.197 CompleteParseASTFactory.java
--- CompleteParseASTFactory.java 15 Nov 2004 21:09:01 -0000 1.197
+++ CompleteParseASTFactory.java 18 Nov 2004 14:04:29 -0000
@@ -1368,7 +1368,7 @@
* Apply the usual arithmetic conversions to find out the result of an expression
* that has a lhs and a rhs as indicated in the specs (section 5.Expressions, page 64)
*/
- protected ITypeInfo usualArithmeticConversions( IASTScope scope, ASTExpression lhsExp, ASTExpression rhsExp) throws ASTSemanticException{
+ protected ITypeInfo usualArithmeticConversions( IASTScope scope, ASTExpression lhsExp, ASTExpression rhsExp, Kind kind) throws ASTSemanticException{
setFilename(lhsExp.getFilename());
ITypeInfo lhs = lhsExp.getResultType().getResult();
@@ -1376,18 +1376,62 @@
if( lhs == null ) return null;
if( rhs == null ) return null;
+ boolean isLhsPointer = false;
+ boolean isRhsPointer = false;
// if you have a variable of type basic type, then we need to go to the basic type first
while( (lhs.getType() == ITypeInfo.t_type) && (lhs.getTypeSymbol() != null)){
+ if (!isLhsPointer) isLhsPointer = lhs.hasPtrOperators();
lhs = lhs.getTypeSymbol().getTypeInfo();
}
while( (rhs.getType() == ITypeInfo.t_type) && (rhs.getTypeSymbol() != null)){
+ if (!isRhsPointer) isRhsPointer = rhs.hasPtrOperators();
rhs = rhs.getTypeSymbol().getTypeInfo();
}
- if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
- handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true );
- if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
- handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true );
+ // invalid arithmetic detection TODO add support for 4.5 Integral Promotions/4.7 Integral Conversions if necessary
+ // 5.6 Multiplicative Operators: The operands of * and / shall have arithmetic or enumeration type; the operands of % shall have integral or enumeration type.
+ if (kind == IASTExpression.Kind.MULTIPLICATIVE_MULTIPLY || kind == IASTExpression.Kind.MULTIPLICATIVE_DIVIDE) {
+ if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ } else if (kind == IASTExpression.Kind.MULTIPLICATIVE_MODULUS) {
+ if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ))
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) ))
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
+
+ // 5.7 Additive Operators:
+ // For addition, either both operands shall have arithmetic or enumeration type, or one operand shall be a
+ // pointer to a completely defined object type and the other shall have integral or enumeration type.
+ // For subtraction, one of the following shall hold:
+ // both operands have arithmetic or enumeration type; or
+ // both operands are pointers to cvqualified or cvunqualified versions of the same completely defined object type; or
+ // the left operand is a pointer to a completely defined object type and the right operand has integral or
+ // enumeration type.
+ } else if (kind == IASTExpression.Kind.ADDITIVE_PLUS) {
+ if (!((isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))) ||
+ (isRhsPointer && (isIntegralType(lhs, isRhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ))))) {
+ if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ }
+ } else if (kind == IASTExpression.Kind.ADDITIVE_MINUS) {
+ if (!(isLhsPointer && (isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )))) {
+ if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ }
+
+ // 5.11, 5.12, 5.13: The operator applies only to integral or enumeration operands.
+ } else if (kind == IASTExpression.Kind.ANDEXPRESSION || kind == IASTExpression.Kind.EXCLUSIVEOREXPRESSION || kind == IASTExpression.Kind.INCLUSIVEOREXPRESSION) {
+ if( !(isIntegralType(lhs, isLhsPointer) || lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ if( !(isIntegralType(rhs, isRhsPointer) || rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator )) )
+ handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true ); // TODO Devin used to be true
+ }
ITypeInfo info = TypeInfoProvider.newTypeInfo( );
if(
@@ -1739,7 +1783,7 @@
ASTExpression left = (ASTExpression)lhs;
ASTExpression right = (ASTExpression)rhs;
if((left != null ) && (right != null)){
- info = usualArithmeticConversions( scope, left, right);
+ info = usualArithmeticConversions( scope, left, right, kind );
}
else
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
@@ -3811,5 +3855,13 @@
this.problemLineNumber = -1;
this.filename = EMPTY_STRING;
}
+ }
+
+ // used to check if an ITypeInfo is an "integral type" based on 3.9.1-7
+ private boolean isIntegralType(ITypeInfo info, boolean isPointer) {
+ if (isPointer) return true;
+ if (info.getType() == ITypeInfo.t_bool || info.getType() == ITypeInfo.t_char || info.getType() == ITypeInfo.t_wchar_t || info.getType() == ITypeInfo.t_int) return true;
+
+ return false;
}
}