mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 16:56:04 +02:00
Patch for Devin Steffler.
Fixed 77821 - usualArithmeticConversions doesn't handle pointers
This commit is contained in:
parent
502f1c4822
commit
deabf0e68b
2 changed files with 67 additions and 6 deletions
|
@ -2332,5 +2332,14 @@ public class CompleteParseASTTest extends CompleteParseBaseTest
|
|||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1368,7 +1368,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
* 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 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
|
||||
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 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
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 );
|
||||
|
@ -3812,4 +3856,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue