1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 09:46:02 +02:00

Unnecessary ambiguity in sizeof expression, bug 252243.

This commit is contained in:
Markus Schorn 2009-03-06 12:56:27 +00:00
parent a3765fa703
commit 4e20a3afa8
4 changed files with 60 additions and 94 deletions

View file

@ -5993,4 +5993,18 @@ public class AST2Tests extends AST2BaseTest {
bh= new BindingAssertionHelper(code, false);
bh.assertProblem("TInt; //ref", 4);
}
// typedef int x, y;
// void func(int c) {
// c= sizeof(x(y));
// x(y);
// }
public void testSizeofFunctionType_252243() throws Exception {
final String code= getAboveComment();
for (ParserLanguage lang : ParserLanguage.values()) {
BindingAssertionHelper ba= new BindingAssertionHelper(code, lang == ParserLanguage.CPP);
ba.assertProblem("y));", 1);
IVariable v= ba.assertNonProblem("y);", 1);
}
}
}

View file

@ -17,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.ASTCompletionNode;
import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
@ -38,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
@ -1776,23 +1774,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
backup(lastTokenOfExpression); consume();
return expressionStatement;
}
// a function call interpreted as declaration: 'func(x);' --> 'func x;'
if (declarators.length == 1) {
IASTName name= ((IASTNamedTypeSpecifier) declspec).getName();
final IASTDeclarator dtor= declarators[0];
if (name.contains(declspec)) {
if (dtor.getNestedDeclarator() != null) {
if (dtor instanceof IASTAmbiguousDeclarator == false
&& dtor instanceof IASTArrayDeclarator == false
&& dtor instanceof IASTFieldDeclarator == false
&& dtor instanceof IASTFunctionDeclarator == false) {
backup(lastTokenOfExpression); consume();
return expressionStatement;
}
}
}
}
}
}
@ -2090,7 +2071,9 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
consume(IToken.tLPAREN);
int typeidOffset= LA(1).getOffset();
typeid= typeId(DeclarationOptions.TYPEID);
if (typeid != null) {
if (!isValidTypeIDForUnaryExpression(unaryExprKind, typeid)) {
typeid= null;
} else {
switch(LT(1)) {
case IToken.tRPAREN:
case IToken.tEOC:
@ -2167,7 +2150,18 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
return ambExpr;
}
protected abstract IASTAmbiguousExpression createAmbiguousExpression();
private boolean isValidTypeIDForUnaryExpression(int unaryExprKind, IASTTypeId typeid) {
if (typeid == null)
return false;
if (unaryExprKind == IASTUnaryExpression.op_sizeof) {
// 5.3.3.1
if (ASTQueries.findTypeRelevantDeclarator(typeid.getAbstractDeclarator()) instanceof IASTFunctionDeclarator)
return false;
}
return true;
}
protected abstract IASTAmbiguousExpression createAmbiguousExpression();
protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr);
protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall);

View file

@ -10,10 +10,8 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -25,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
@ -36,22 +35,10 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
* Visitor to resolve ast ambiguities in the right order
*/
final class CPPASTAmbiguityResolver extends ASTVisitor {
private static class ClassContext {
ArrayList<IASTNode> fDeferredNodes;
final IASTNode fNode;
public ClassContext(IASTNode node) {
fNode= node;
}
public void deferNode(IASTNode node) {
if (fDeferredNodes == null)
fDeferredNodes= new ArrayList<IASTNode>();
fDeferredNodes.add(node);
}
}
private LinkedList<ClassContext> fContextStack;
private ClassContext fCurrentContext;
private int fSkipInitializers= 0;
private int fDeferFunctions= 1;
private HashSet<IASTDeclaration> fRepopulate= new HashSet<IASTDeclaration>();
private LinkedList<IASTNode> fDeferredNodes= new LinkedList<IASTNode>();
public CPPASTAmbiguityResolver() {
super(false);
@ -60,6 +47,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
shouldVisitDeclarations= true;
shouldVisitDeclSpecifiers= true;
shouldVisitInitializers= true;
shouldVisitTranslationUnit= true;
}
@Override
@ -91,13 +79,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
@Override
public int visit(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
if (fCurrentContext != null) {
// defer visiting nested classes until the outer class body has been visited.
fCurrentContext.deferNode(declSpec);
return PROCESS_SKIP;
}
pushContext();
fCurrentContext= new ClassContext(declSpec);
fDeferFunctions++;
}
return PROCESS_CONTINUE;
}
@ -105,46 +87,14 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
@Override
public int leave(IASTDeclSpecifier declSpec) {
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
assert fCurrentContext != null;
assert fCurrentContext.fNode == declSpec;
if (fCurrentContext != null) {
final List<IASTNode> deferredNodes = fCurrentContext.fDeferredNodes;
fCurrentContext= null;
if (deferredNodes != null) {
for (IASTNode node : deferredNodes) {
node.accept(this);
}
}
popContext();
}
fDeferFunctions--;
}
return PROCESS_CONTINUE;
}
private void pushContext() {
if (fCurrentContext==null) {
if (fContextStack != null && !fContextStack.isEmpty()) {
fContextStack.addLast(null);
}
} else {
if (fContextStack == null) {
fContextStack= new LinkedList<ClassContext>();
}
fContextStack.addLast(fCurrentContext);
}
}
private void popContext() {
if (fContextStack == null || fContextStack.isEmpty()) {
fCurrentContext= null;
} else {
fCurrentContext= fContextStack.removeLast();
}
}
@Override
public int visit(IASTDeclaration decl) {
if (decl instanceof IASTFunctionDefinition) {
if (fDeferFunctions > 0 && decl instanceof IASTFunctionDefinition) {
final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
// visit the declarator first, it may contain ambiguous template arguments needed
@ -152,13 +102,10 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
fSkipInitializers++;
ASTQueries.findOutermostDeclarator(fdef.getDeclarator()).accept(this);
fSkipInitializers--;
if (fCurrentContext != null) {
// defer visiting the body of the function until the class body has been visited.
fdef.getDeclSpecifier().accept(this);
fCurrentContext.deferNode(decl);
return PROCESS_SKIP;
}
fdef.getDeclSpecifier().accept(this);
// defer visiting the body of the function until the class body has been visited.
fDeferredNodes.add(decl);
return PROCESS_SKIP;
}
return PROCESS_CONTINUE;
}
@ -171,6 +118,23 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
return PROCESS_CONTINUE;
}
@Override
public int visit(IASTInitializer initializer) {
if (fSkipInitializers > 0)
return PROCESS_SKIP;
return PROCESS_CONTINUE;
}
@Override
public int leave(IASTTranslationUnit tu) {
while (!fDeferredNodes.isEmpty()) {
fDeferFunctions= 0;
fDeferredNodes.removeFirst().accept(this);
}
return PROCESS_CONTINUE;
}
private void repopulateScope(IASTDeclaration declaration) {
IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration);
if (scope instanceof ICPPASTInternalScope) {
@ -183,12 +147,4 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration);
}
}
@Override
public int visit(IASTInitializer initializer) {
if (fSkipInitializers > 0)
return PROCESS_SKIP;
return PROCESS_CONTINUE;
}
}

View file

@ -271,13 +271,15 @@ public class LookupData {
return true;
}
if (p1 instanceof IASTExpression) {
ASTNodeProperty prop = p1.getPropertyInParent();
if (p1 instanceof IASTIdExpression) {
p1= p1.getParent();
}
while (p1 instanceof IASTUnaryExpression && ((IASTUnaryExpression) p1).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
prop = p1.getPropertyInParent();
p1= p1.getParent();
}
if (p1 instanceof IASTFunctionCallExpression) {
if (p1 instanceof IASTFunctionCallExpression && prop == IASTFunctionCallExpression.FUNCTION_NAME) {
return true;
}
} else if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {