From a96b73e8a854d97554be7df490c2f58527919fa0 Mon Sep 17 00:00:00 2001 From: Christian Banse Date: Tue, 3 Aug 2021 15:28:21 +0200 Subject: [PATCH] CXX static field acecss (#492) --- .../declarations/FunctionDeclaration.java | 2 +- .../cpg/passes/VariableUsageResolver.java | 14 ++++++ .../cpp/CXXLanguageFrontendTest.java | 44 ++++++++----------- cpg-library/src/test/resources/recordstmt.cpp | 3 ++ 4 files changed, 36 insertions(+), 27 deletions(-) diff --git a/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/graph/declarations/FunctionDeclaration.java b/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/graph/declarations/FunctionDeclaration.java index 28f8340449..d929100434 100644 --- a/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/graph/declarations/FunctionDeclaration.java +++ b/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/graph/declarations/FunctionDeclaration.java @@ -210,7 +210,7 @@ public T getBodyStatementAs(int i, Class clazz) { return null; } - return statement.getClass().isAssignableFrom(clazz) ? clazz.cast(statement) : null; + return clazz.isAssignableFrom(statement.getClass()) ? clazz.cast(statement) : null; } return null; diff --git a/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/passes/VariableUsageResolver.java b/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/passes/VariableUsageResolver.java index 39d5457306..2bfb726ee8 100644 --- a/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/passes/VariableUsageResolver.java +++ b/cpg-library/src/main/java/de/fraunhofer/aisec/cpg/passes/VariableUsageResolver.java @@ -232,6 +232,20 @@ private void resolveLocalVarUsage(RecordDeclaration currentClass, Node parent, N } } + // TODO: we need to do proper scoping (and merge it with the code above), but for now this + // just enables CXX static fields + if (refersTo.isEmpty() && current.getName().contains(lang.getNamespaceDelimiter())) { + var path = + Arrays.asList(current.getName().split(Pattern.quote(lang.getNamespaceDelimiter()))); + recordDeclType = + TypeParser.createFrom( + String.join(lang.getNamespaceDelimiter(), path.subList(0, path.size() - 1)), true); + var field = resolveMember(recordDeclType, (DeclaredReferenceExpression) current); + if (field != null) { + refersTo = Optional.of(field); + } + } + if (refersTo.isPresent()) { ref.setRefersTo(refersTo.get()); } else { diff --git a/cpg-library/src/test/java/de/fraunhofer/aisec/cpg/frontends/cpp/CXXLanguageFrontendTest.java b/cpg-library/src/test/java/de/fraunhofer/aisec/cpg/frontends/cpp/CXXLanguageFrontendTest.java index df6f109831..20171c5462 100644 --- a/cpg-library/src/test/java/de/fraunhofer/aisec/cpg/frontends/cpp/CXXLanguageFrontendTest.java +++ b/cpg-library/src/test/java/de/fraunhofer/aisec/cpg/frontends/cpp/CXXLanguageFrontendTest.java @@ -25,12 +25,7 @@ */ package de.fraunhofer.aisec.cpg.frontends.cpp; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.junit.jupiter.api.Assertions.fail; +import static org.junit.jupiter.api.Assertions.*; import de.fraunhofer.aisec.cpg.BaseTest; import de.fraunhofer.aisec.cpg.TestUtils; @@ -57,20 +52,7 @@ import de.fraunhofer.aisec.cpg.graph.statements.Statement; import de.fraunhofer.aisec.cpg.graph.statements.SwitchStatement; import de.fraunhofer.aisec.cpg.graph.statements.TryStatement; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.ArraySubscriptionExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.BinaryOperator; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.CallExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.CastExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.ConstructExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.DeclaredReferenceExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.DesignatedInitializerExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.InitializerListExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.Literal; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.MemberCallExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.NewExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.TypeIdExpression; -import de.fraunhofer.aisec.cpg.graph.statements.expressions.UnaryOperator; +import de.fraunhofer.aisec.cpg.graph.statements.expressions.*; import de.fraunhofer.aisec.cpg.graph.types.ObjectType; import de.fraunhofer.aisec.cpg.graph.types.TypeParser; import de.fraunhofer.aisec.cpg.graph.types.UnknownType; @@ -761,13 +743,13 @@ void testRecordDeclaration() throws Exception { assertEquals("SomeClass", recordDeclaration.getName()); assertEquals("class", recordDeclaration.getKind()); - assertEquals(2, recordDeclaration.getFields().size()); + assertEquals(3, recordDeclaration.getFields().size()); - FieldDeclaration field = - recordDeclaration.getFields().stream() - .filter(f -> f.getName().equals("field")) - .findFirst() - .get(); + var field = recordDeclaration.getField("field"); + assertNotNull(field); + + var constant = recordDeclaration.getField("CONSTANT"); + assertNotNull(constant); assertEquals(TypeParser.createFrom("void*", true), field.getType()); @@ -828,6 +810,16 @@ void testRecordDeclaration() throws Exception { assertNotNull(constructorDeclaration); assertFalse(constructorDeclaration.isDefinition()); assertEquals(constructorDefinition, constructorDeclaration.getDefinition()); + + var main = + declaration.getDeclarationsByName("main", FunctionDeclaration.class).iterator().next(); + assertNotNull(main); + + var methodCallWithConstant = main.getBodyStatementAs(2, CallExpression.class); + assertNotNull(methodCallWithConstant); + + var arg = methodCallWithConstant.getArguments().get(0); + assertSame(constant, ((DeclaredReferenceExpression) arg).getRefersTo()); } @Test diff --git a/cpg-library/src/test/resources/recordstmt.cpp b/cpg-library/src/test/resources/recordstmt.cpp index 0c786b28f6..83b8a5d0b3 100644 --- a/cpg-library/src/test/resources/recordstmt.cpp +++ b/cpg-library/src/test/resources/recordstmt.cpp @@ -1,4 +1,6 @@ class SomeClass { + static const int CONSTANT = 8; + private: void* field = 0; @@ -32,4 +34,5 @@ SomeClass::SomeClass(int a) { int main() { SomeClass s; s.method(); + s.method(SomeClass::CONSTANT); }