mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Unnecessary ambiguity in sizeof expression, bug 252243.
This commit is contained in:
parent
a3765fa703
commit
4e20a3afa8
4 changed files with 60 additions and 94 deletions
|
@ -5993,4 +5993,18 @@ public class AST2Tests extends AST2BaseTest {
|
||||||
bh= new BindingAssertionHelper(code, false);
|
bh= new BindingAssertionHelper(code, false);
|
||||||
bh.assertProblem("TInt; //ref", 4);
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.ASTGenericVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
|
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.IASTBinaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement;
|
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.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
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.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
@ -1776,23 +1774,6 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
backup(lastTokenOfExpression); consume();
|
backup(lastTokenOfExpression); consume();
|
||||||
return expressionStatement;
|
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);
|
consume(IToken.tLPAREN);
|
||||||
int typeidOffset= LA(1).getOffset();
|
int typeidOffset= LA(1).getOffset();
|
||||||
typeid= typeId(DeclarationOptions.TYPEID);
|
typeid= typeId(DeclarationOptions.TYPEID);
|
||||||
if (typeid != null) {
|
if (!isValidTypeIDForUnaryExpression(unaryExprKind, typeid)) {
|
||||||
|
typeid= null;
|
||||||
|
} else {
|
||||||
switch(LT(1)) {
|
switch(LT(1)) {
|
||||||
case IToken.tRPAREN:
|
case IToken.tRPAREN:
|
||||||
case IToken.tEOC:
|
case IToken.tEOC:
|
||||||
|
@ -2167,6 +2150,17 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
|
||||||
return ambExpr;
|
return ambExpr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 createAmbiguousExpression();
|
||||||
protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr);
|
protected abstract IASTAmbiguousExpression createAmbiguousBinaryVsCastExpression(IASTBinaryExpression binary, IASTCastExpression castExpr);
|
||||||
protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall);
|
protected abstract IASTAmbiguousExpression createAmbiguousCastVsFunctionCallExpression(IASTCastExpression castExpr, IASTFunctionCallExpression funcCall);
|
||||||
|
|
|
@ -10,10 +10,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
package org.eclipse.cdt.internal.core.dom.parser.cpp;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
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.IASTInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
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.IScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
|
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
|
* Visitor to resolve ast ambiguities in the right order
|
||||||
*/
|
*/
|
||||||
final class CPPASTAmbiguityResolver extends ASTVisitor {
|
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 fSkipInitializers= 0;
|
||||||
|
private int fDeferFunctions= 1;
|
||||||
private HashSet<IASTDeclaration> fRepopulate= new HashSet<IASTDeclaration>();
|
private HashSet<IASTDeclaration> fRepopulate= new HashSet<IASTDeclaration>();
|
||||||
|
private LinkedList<IASTNode> fDeferredNodes= new LinkedList<IASTNode>();
|
||||||
|
|
||||||
public CPPASTAmbiguityResolver() {
|
public CPPASTAmbiguityResolver() {
|
||||||
super(false);
|
super(false);
|
||||||
|
@ -60,6 +47,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
shouldVisitDeclarations= true;
|
shouldVisitDeclarations= true;
|
||||||
shouldVisitDeclSpecifiers= true;
|
shouldVisitDeclSpecifiers= true;
|
||||||
shouldVisitInitializers= true;
|
shouldVisitInitializers= true;
|
||||||
|
shouldVisitTranslationUnit= true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,13 +79,7 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTDeclSpecifier declSpec) {
|
public int visit(IASTDeclSpecifier declSpec) {
|
||||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
||||||
if (fCurrentContext != null) {
|
fDeferFunctions++;
|
||||||
// defer visiting nested classes until the outer class body has been visited.
|
|
||||||
fCurrentContext.deferNode(declSpec);
|
|
||||||
return PROCESS_SKIP;
|
|
||||||
}
|
|
||||||
pushContext();
|
|
||||||
fCurrentContext= new ClassContext(declSpec);
|
|
||||||
}
|
}
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
@ -105,46 +87,14 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
@Override
|
@Override
|
||||||
public int leave(IASTDeclSpecifier declSpec) {
|
public int leave(IASTDeclSpecifier declSpec) {
|
||||||
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
if (declSpec instanceof ICPPASTCompositeTypeSpecifier) {
|
||||||
assert fCurrentContext != null;
|
fDeferFunctions--;
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return PROCESS_CONTINUE;
|
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
|
@Override
|
||||||
public int visit(IASTDeclaration decl) {
|
public int visit(IASTDeclaration decl) {
|
||||||
if (decl instanceof IASTFunctionDefinition) {
|
if (fDeferFunctions > 0 && decl instanceof IASTFunctionDefinition) {
|
||||||
final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
|
final IASTFunctionDefinition fdef= (IASTFunctionDefinition) decl;
|
||||||
|
|
||||||
// visit the declarator first, it may contain ambiguous template arguments needed
|
// visit the declarator first, it may contain ambiguous template arguments needed
|
||||||
|
@ -152,14 +102,11 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
fSkipInitializers++;
|
fSkipInitializers++;
|
||||||
ASTQueries.findOutermostDeclarator(fdef.getDeclarator()).accept(this);
|
ASTQueries.findOutermostDeclarator(fdef.getDeclarator()).accept(this);
|
||||||
fSkipInitializers--;
|
fSkipInitializers--;
|
||||||
|
|
||||||
if (fCurrentContext != null) {
|
|
||||||
// defer visiting the body of the function until the class body has been visited.
|
|
||||||
fdef.getDeclSpecifier().accept(this);
|
fdef.getDeclSpecifier().accept(this);
|
||||||
fCurrentContext.deferNode(decl);
|
// defer visiting the body of the function until the class body has been visited.
|
||||||
|
fDeferredNodes.add(decl);
|
||||||
return PROCESS_SKIP;
|
return PROCESS_SKIP;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return PROCESS_CONTINUE;
|
return PROCESS_CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,6 +118,23 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
return PROCESS_CONTINUE;
|
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) {
|
private void repopulateScope(IASTDeclaration declaration) {
|
||||||
IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration);
|
IScope scope= CPPVisitor.getContainingNonTemplateScope(declaration);
|
||||||
if (scope instanceof ICPPASTInternalScope) {
|
if (scope instanceof ICPPASTInternalScope) {
|
||||||
|
@ -183,12 +147,4 @@ final class CPPASTAmbiguityResolver extends ASTVisitor {
|
||||||
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration);
|
CPPSemantics.populateCache((ICPPASTInternalScope) scope, declaration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public int visit(IASTInitializer initializer) {
|
|
||||||
if (fSkipInitializers > 0)
|
|
||||||
return PROCESS_SKIP;
|
|
||||||
|
|
||||||
return PROCESS_CONTINUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -271,13 +271,15 @@ public class LookupData {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (p1 instanceof IASTExpression) {
|
if (p1 instanceof IASTExpression) {
|
||||||
|
ASTNodeProperty prop = p1.getPropertyInParent();
|
||||||
if (p1 instanceof IASTIdExpression) {
|
if (p1 instanceof IASTIdExpression) {
|
||||||
p1= p1.getParent();
|
p1= p1.getParent();
|
||||||
}
|
}
|
||||||
while (p1 instanceof IASTUnaryExpression && ((IASTUnaryExpression) p1).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
while (p1 instanceof IASTUnaryExpression && ((IASTUnaryExpression) p1).getOperator() == IASTUnaryExpression.op_bracketedPrimary) {
|
||||||
|
prop = p1.getPropertyInParent();
|
||||||
p1= p1.getParent();
|
p1= p1.getParent();
|
||||||
}
|
}
|
||||||
if (p1 instanceof IASTFunctionCallExpression) {
|
if (p1 instanceof IASTFunctionCallExpression && prop == IASTFunctionCallExpression.FUNCTION_NAME) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {
|
} else if (p1 instanceof ICPPASTNamedTypeSpecifier && p2 instanceof IASTTypeId) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue