mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +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$
|
writer.write("#endif\n"); //$NON-NLS-1$
|
||||||
parse(writer.toString());
|
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
|
* 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)
|
* 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());
|
setFilename(lhsExp.getFilename());
|
||||||
|
|
||||||
ITypeInfo lhs = lhsExp.getResultType().getResult();
|
ITypeInfo lhs = lhsExp.getResultType().getResult();
|
||||||
|
@ -1376,18 +1376,62 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
|
|
||||||
if( lhs == null ) return null;
|
if( lhs == null ) return null;
|
||||||
if( rhs == 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
|
// 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)){
|
while( (lhs.getType() == ITypeInfo.t_type) && (lhs.getTypeSymbol() != null)){
|
||||||
|
if (!isLhsPointer) isLhsPointer = lhs.hasPtrOperators();
|
||||||
lhs = lhs.getTypeSymbol().getTypeInfo();
|
lhs = lhs.getTypeSymbol().getTypeInfo();
|
||||||
}
|
}
|
||||||
while( (rhs.getType() == ITypeInfo.t_type) && (rhs.getTypeSymbol() != null)){
|
while( (rhs.getType() == ITypeInfo.t_type) && (rhs.getTypeSymbol() != null)){
|
||||||
|
if (!isRhsPointer) isRhsPointer = rhs.hasPtrOperators();
|
||||||
rhs = rhs.getTypeSymbol().getTypeInfo();
|
rhs = rhs.getTypeSymbol().getTypeInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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 ) )
|
if( !lhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
|
||||||
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, lhsExp.getStartingOffset(), lhsExp.getEndingOffset(), lhsExp.getStartingLine(), true );
|
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 ) )
|
if( !rhs.isType(ITypeInfo.t__Bool, ITypeInfo.t_enumerator ) )
|
||||||
handleProblem( scope, IProblem.SEMANTIC_INVALID_CONVERSION_TYPE, null, rhsExp.getStartingOffset(), rhsExp.getEndingOffset(), rhsExp.getStartingLine(), true );
|
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( );
|
ITypeInfo info = TypeInfoProvider.newTypeInfo( );
|
||||||
if(
|
if(
|
||||||
|
@ -1739,7 +1783,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
ASTExpression left = (ASTExpression)lhs;
|
ASTExpression left = (ASTExpression)lhs;
|
||||||
ASTExpression right = (ASTExpression)rhs;
|
ASTExpression right = (ASTExpression)rhs;
|
||||||
if((left != null ) && (right != null)){
|
if((left != null ) && (right != null)){
|
||||||
info = usualArithmeticConversions( scope, left, right);
|
info = usualArithmeticConversions( scope, left, right, kind );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
|
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
|
||||||
|
@ -3812,4 +3856,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
this.filename = EMPTY_STRING;
|
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