Search in sources :

Example 1 with ParameterizedType

use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.

the class FunctionTemplateTest method testFunctionTemplateStructure.

@Test
void testFunctionTemplateStructure() throws Exception {
    List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "functionTemplate.cpp").toFile()), topLevel, true);
    // This test checks the structure of FunctionTemplates without the TemplateExpansionPass
    FunctionTemplateDeclaration functionTemplateDeclaration = TestUtils.subnodesOfType(result, FunctionTemplateDeclaration.class).get(0);
    // Check FunctionTemplate Parameters
    List<TypeParamDeclaration> typeParamDeclarations = TestUtils.subnodesOfType(result, TypeParamDeclaration.class);
    assertEquals(1, typeParamDeclarations.size());
    TypeParamDeclaration typeParamDeclaration = typeParamDeclarations.get(0);
    assertEquals(typeParamDeclaration, functionTemplateDeclaration.getParameters().get(0));
    ParameterizedType T = new ParameterizedType("T");
    ObjectType intType = new ObjectType("int", Type.Storage.AUTO, new Type.Qualifier(), new ArrayList<>(), ObjectType.Modifier.SIGNED, true);
    ObjectType floatType = new ObjectType("float", Type.Storage.AUTO, new Type.Qualifier(), new ArrayList<>(), ObjectType.Modifier.SIGNED, true);
    assertEquals(T, typeParamDeclaration.getType());
    assertEquals(intType, typeParamDeclaration.getDefault());
    ParamVariableDeclaration N = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ParamVariableDeclaration.class), "N");
    Literal<Integer> int2 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(2));
    Literal<Integer> int3 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(3));
    Literal<Integer> int5 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(5));
    assertEquals(N, functionTemplateDeclaration.getParameters().get(1));
    assertEquals(intType, N.getType());
    assertEquals(5, ((Literal) N.getDefault()).getValue());
    assertTrue(N.getPrevDFG().contains(int5));
    assertTrue(N.getPrevDFG().contains(int3));
    assertTrue(N.getPrevDFG().contains(int2));
    // Check the realization
    assertEquals(1, functionTemplateDeclaration.getRealization().size());
    FunctionDeclaration fixed_multiply = functionTemplateDeclaration.getRealization().get(0);
    assertEquals(T, fixed_multiply.getType());
    ParamVariableDeclaration val = fixed_multiply.getParameters().get(0);
    assertEquals(T, val.getType());
    // Check the invokes
    CallExpression callInt2 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, CallExpression.class), c -> c.getLocation().getRegion().getStartLine() == 12);
    assertEquals(1, callInt2.getInvokes().size());
    assertEquals(fixed_multiply, callInt2.getInvokes().get(0));
    CallExpression callFloat3 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, CallExpression.class), c -> c.getLocation().getRegion().getStartLine() == 13);
    assertEquals(1, callFloat3.getInvokes().size());
    assertEquals(fixed_multiply, callFloat3.getInvokes().get(0));
    // Check return values
    assertEquals(intType, callInt2.getType());
    assertEquals(floatType, callFloat3.getType());
    // Check template arguments
    testFunctionTemplateArguments(callFloat3, floatType, int3);
}
Also used : ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) ObjectType(de.fraunhofer.aisec.cpg.graph.types.ObjectType) UnknownType(de.fraunhofer.aisec.cpg.graph.types.UnknownType) Type(de.fraunhofer.aisec.cpg.graph.types.Type) ObjectType(de.fraunhofer.aisec.cpg.graph.types.ObjectType) ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Test(org.junit.jupiter.api.Test)

Example 2 with ParameterizedType

use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.

the class ClassTemplateTest method testReferenceInTemplates.

@Test
void testReferenceInTemplates() throws Exception {
    // Test array.cpp: checks usage of referencetype of parameterized type (T[])
    TypeManager.reset();
    List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "array.cpp").toFile()), topLevel, true);
    ClassTemplateDeclaration template = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ClassTemplateDeclaration.class), "template<typename T, int N=10> class Array");
    RecordDeclaration array = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, RecordDeclaration.class), "Array");
    ParamVariableDeclaration N = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ParamVariableDeclaration.class), "N");
    TypeParamDeclaration T = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "typename T");
    Literal<?> literal10 = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, Literal.class), l -> l.getValue().equals(10));
    FieldDeclaration thisField = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "this");
    FieldDeclaration m_Array = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "m_Array");
    assertEquals(2, template.getParameters().size());
    assertEquals(T, template.getParameters().get(0));
    assertEquals(N, template.getParameters().get(1));
    assertEquals(literal10, N.getDefault());
    assertEquals(2, array.getFields().size());
    assertEquals(thisField, array.getFields().get(0));
    assertEquals(m_Array, array.getFields().get(1));
    ObjectType arrayType = (ObjectType) thisField.getType();
    assertEquals(1, arrayType.getGenerics().size());
    assertEquals("T", arrayType.getGenerics().get(0).getName());
    ParameterizedType typeT = (ParameterizedType) arrayType.getGenerics().get(0);
    assertEquals(typeT, T.getType());
    assertTrue(m_Array.getType() instanceof PointerType);
    PointerType tArray = (PointerType) m_Array.getType();
    assertEquals(typeT, tArray.getElementType());
    ConstructExpression constructExpression = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, ConstructExpression.class), c -> c.getCode().equals("()"));
    assertEquals(template, constructExpression.getTemplateInstantiation());
    assertEquals(array, constructExpression.getInstantiates());
    assertEquals("int", constructExpression.getTemplateParameters().get(0).getName());
    assertEquals(literal10, constructExpression.getTemplateParameters().get(1));
    assertEquals("Array", constructExpression.getType().getName());
    ObjectType instantiatedType = (ObjectType) constructExpression.getType();
    assertEquals(1, instantiatedType.getGenerics().size());
    assertEquals("int", instantiatedType.getGenerics().get(0).getName());
}
Also used : PointerType(de.fraunhofer.aisec.cpg.graph.types.PointerType) ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) ObjectType(de.fraunhofer.aisec.cpg.graph.types.ObjectType) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Test(org.junit.jupiter.api.Test)

Example 3 with ParameterizedType

use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.

the class ClassTemplateTest method testStructTemplateWithSameDefaultType.

@Test
void testStructTemplateWithSameDefaultType() throws Exception {
    // Test pair3.cpp: Template a struct instead of a class and use a Type1 as default of Type2
    TypeManager.reset();
    List<TranslationUnitDeclaration> result = TestUtils.analyze(List.of(Path.of(topLevel.toString(), "pair3.cpp").toFile()), topLevel, true);
    ClassTemplateDeclaration template = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ClassTemplateDeclaration.class), "template<class Type1, class Type2 = Type1> struct Pair");
    RecordDeclaration pair = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, RecordDeclaration.class), "Pair");
    ConstructorDeclaration pairConstructorDeclaration = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, ConstructorDeclaration.class), "Pair");
    TypeParamDeclaration type1 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "class Type1");
    TypeParamDeclaration type2 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, TypeParamDeclaration.class), "class Type2 = Type1");
    FieldDeclaration first = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "first");
    FieldDeclaration second = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, FieldDeclaration.class), "second");
    VariableDeclaration point1 = TestUtils.findByUniqueName(TestUtils.subnodesOfType(result, VariableDeclaration.class), "point1");
    ConstructExpression constructExpression = TestUtils.findByUniquePredicate(TestUtils.subnodesOfType(result, ConstructExpression.class), c -> c.getCode().equals("()"));
    assertEquals(1, template.getRealization().size());
    assertEquals(pair, template.getRealization().get(0));
    assertEquals(2, template.getParameters().size());
    assertEquals(type1, template.getParameters().get(0));
    assertEquals(type2, template.getParameters().get(1));
    assertEquals("Type1", type1.getType().getName());
    ParameterizedType type1ParameterizedType = (ParameterizedType) type1.getType();
    assertEquals("Type2", type2.getType().getName());
    ParameterizedType type2ParameterizedType = (ParameterizedType) type2.getType();
    assertEquals(type1ParameterizedType, type2.getDefault());
    ObjectType pairType = (ObjectType) pairConstructorDeclaration.getType();
    assertEquals(2, pairType.getGenerics().size());
    assertEquals(type1ParameterizedType, pairType.getGenerics().get(0));
    assertEquals(type2ParameterizedType, pairType.getGenerics().get(1));
    // cpp has implicit `this` field
    assertEquals(3, pair.getFields().size());
    assertEquals(first, pair.getFields().get(1));
    assertEquals(second, pair.getFields().get(2));
    assertEquals(type1ParameterizedType, first.getType());
    assertEquals(type2ParameterizedType, second.getType());
    testStructTemplateWithSameDefaultTypeInvocation(template, pair, pairConstructorDeclaration, constructExpression, point1);
}
Also used : ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) ObjectType(de.fraunhofer.aisec.cpg.graph.types.ObjectType) BaseTest(de.fraunhofer.aisec.cpg.BaseTest) Test(org.junit.jupiter.api.Test)

Example 4 with ParameterizedType

use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.

the class DeclarationHandler method handleFieldDeclaration.

public de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration handleFieldDeclaration(com.github.javaparser.ast.body.FieldDeclaration fieldDecl) {
    // TODO: can  field have more than one variable?
    VariableDeclarator variable = fieldDecl.getVariable(0);
    List<String> modifiers = fieldDecl.getModifiers().stream().map(modifier -> modifier.getKeyword().asString()).collect(Collectors.toList());
    String joinedModifiers = String.join(" ", modifiers) + " ";
    PhysicalLocation location = this.lang.getLocationFromRawNode(fieldDecl);
    Expression initializer = (Expression) variable.getInitializer().map(this.lang.getExpressionHandler()::handle).orElse(null);
    Type type;
    try {
        // Resolve type first with ParameterizedType
        type = TypeManager.getInstance().getTypeParameter(this.lang.getScopeManager().getCurrentRecord(), variable.resolve().getType().describe());
        if (type == null) {
            type = TypeParser.createFrom(joinedModifiers + variable.resolve().getType().describe(), true);
        }
    } catch (UnsolvedSymbolException | UnsupportedOperationException e) {
        String t = this.lang.recoverTypeFromUnsolvedException(e);
        if (t == null) {
            log.warn("Could not resolve type for {}", variable);
            type = TypeParser.createFrom(joinedModifiers + variable.getType().asString(), true);
        } else {
            type = TypeParser.createFrom(joinedModifiers + t, true);
            type.setTypeOrigin(Type.Origin.GUESSED);
        }
    }
    de.fraunhofer.aisec.cpg.graph.declarations.FieldDeclaration fieldDeclaration = newFieldDeclaration(variable.getName().asString(), type, modifiers, variable.toString(), location, initializer, false);
    lang.getScopeManager().addDeclaration(fieldDeclaration);
    this.lang.processAnnotations(fieldDeclaration, fieldDecl);
    return fieldDeclaration;
}
Also used : NodeBuilder(de.fraunhofer.aisec.cpg.graph.NodeBuilder) TypeParser(de.fraunhofer.aisec.cpg.graph.types.TypeParser) ProblemDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.ProblemDeclaration) UnknownType(de.fraunhofer.aisec.cpg.graph.types.UnknownType) ReturnStmt(com.github.javaparser.ast.stmt.ReturnStmt) Parameter(com.github.javaparser.ast.body.Parameter) AnnotationMemberDeclaration(com.github.javaparser.ast.body.AnnotationMemberDeclaration) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) ImportDeclaration(com.github.javaparser.ast.ImportDeclaration) ProblemNode(de.fraunhofer.aisec.cpg.graph.ProblemNode) Map(java.util.Map) ParamVariableDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.ParamVariableDeclaration) Handler(de.fraunhofer.aisec.cpg.frontends.Handler) NodeList(com.github.javaparser.ast.NodeList) Declaration(de.fraunhofer.aisec.cpg.graph.declarations.Declaration) ResolvedMethodDeclaration(com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration) UnsolvedSymbolException(com.github.javaparser.resolution.UnsolvedSymbolException) TypeManager(de.fraunhofer.aisec.cpg.graph.TypeManager) RecordDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration) Type(de.fraunhofer.aisec.cpg.graph.types.Type) ResolvedConstructorDeclaration(com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration) BodyDeclaration(com.github.javaparser.ast.body.BodyDeclaration) Statement(com.github.javaparser.ast.stmt.Statement) Collectors(java.util.stream.Collectors) InitializerDeclaration(com.github.javaparser.ast.body.InitializerDeclaration) PhysicalLocation(de.fraunhofer.aisec.cpg.sarif.PhysicalLocation) Expression(de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression) List(java.util.List) CompoundStatement(de.fraunhofer.aisec.cpg.graph.statements.CompoundStatement) Optional(java.util.Optional) AnnotationDeclaration(com.github.javaparser.ast.body.AnnotationDeclaration) BlockStmt(com.github.javaparser.ast.stmt.BlockStmt) ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) RecordScope(de.fraunhofer.aisec.cpg.passes.scopes.RecordScope) ClassOrInterfaceDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) UnsolvedSymbolException(com.github.javaparser.resolution.UnsolvedSymbolException) VariableDeclarator(com.github.javaparser.ast.body.VariableDeclarator) UnknownType(de.fraunhofer.aisec.cpg.graph.types.UnknownType) Type(de.fraunhofer.aisec.cpg.graph.types.Type) ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) Expression(de.fraunhofer.aisec.cpg.graph.statements.expressions.Expression) PhysicalLocation(de.fraunhofer.aisec.cpg.sarif.PhysicalLocation)

Example 5 with ParameterizedType

use of de.fraunhofer.aisec.cpg.graph.types.ParameterizedType in project cpg by Fraunhofer-AISEC.

the class DeclarationHandler method handleClassOrInterfaceDeclaration.

public RecordDeclaration handleClassOrInterfaceDeclaration(ClassOrInterfaceDeclaration classInterDecl) {
    // TODO: support other kinds, such as interfaces
    String fqn = classInterDecl.getNameAsString();
    // Todo adapt name using a new type of scope "Namespace/Package scope"
    // if (packageDeclaration != null) {
    // name = packageDeclaration.getNameAsString() + "." + name;
    // }
    fqn = getAbsoluteName(fqn);
    // add a type declaration
    RecordDeclaration recordDeclaration = newRecordDeclaration(fqn, "class", null, true, lang, classInterDecl);
    recordDeclaration.setSuperClasses(classInterDecl.getExtendedTypes().stream().map(this.lang::getTypeAsGoodAsPossible).collect(Collectors.toList()));
    recordDeclaration.setImplementedInterfaces(classInterDecl.getImplementedTypes().stream().map(this.lang::getTypeAsGoodAsPossible).collect(Collectors.toList()));
    TypeManager.getInstance().addTypeParameter(recordDeclaration, classInterDecl.getTypeParameters().stream().map(t -> new ParameterizedType(t.getNameAsString())).collect(Collectors.toList()));
    Map<Boolean, List<String>> partitioned = this.lang.getContext().getImports().stream().collect(Collectors.partitioningBy(ImportDeclaration::isStatic, Collectors.mapping(i -> {
        String iName = i.getNameAsString();
        // we need to ensure that x.* imports really preserve the asterisk!
        if (i.isAsterisk() && !iName.endsWith(".*")) {
            iName += ".*";
        }
        return iName;
    }, Collectors.toList())));
    recordDeclaration.setStaticImportStatements(partitioned.get(true));
    recordDeclaration.setImportStatements(partitioned.get(false));
    lang.getScopeManager().enterScope(recordDeclaration);
    lang.getScopeManager().addDeclaration(recordDeclaration.getThis());
    // TODO: 'this' identifier for multiple instances?
    for (BodyDeclaration<?> decl : classInterDecl.getMembers()) {
        if (decl instanceof com.github.javaparser.ast.body.FieldDeclaration) {
            // will be added via the scopemanager
            handle(decl);
        } else if (decl instanceof com.github.javaparser.ast.body.MethodDeclaration) {
            de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration md = (de.fraunhofer.aisec.cpg.graph.declarations.MethodDeclaration) handle(decl);
            recordDeclaration.addMethod(md);
        } else if (decl instanceof com.github.javaparser.ast.body.ConstructorDeclaration) {
            de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration c = (de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration) handle(decl);
            recordDeclaration.addConstructor(c);
        } else if (decl instanceof com.github.javaparser.ast.body.ClassOrInterfaceDeclaration) {
            recordDeclaration.addDeclaration(handle(decl));
        } else if (decl instanceof com.github.javaparser.ast.body.InitializerDeclaration) {
            InitializerDeclaration id = (InitializerDeclaration) decl;
            CompoundStatement initializerBlock = lang.getStatementHandler().handleBlockStatement(id.getBody());
            initializerBlock.setStaticBlock(id.isStatic());
            recordDeclaration.addStatement(initializerBlock);
        } else {
            log.debug("Member {} of type {} is something that we do not parse yet: {}", decl, recordDeclaration.getName(), decl.getClass().getSimpleName());
        }
    }
    if (recordDeclaration.getConstructors().isEmpty()) {
        de.fraunhofer.aisec.cpg.graph.declarations.ConstructorDeclaration constructorDeclaration = newConstructorDeclaration(recordDeclaration.getName(), recordDeclaration.getName(), recordDeclaration);
        recordDeclaration.addConstructor(constructorDeclaration);
        lang.getScopeManager().addDeclaration(constructorDeclaration);
    }
    lang.processAnnotations(recordDeclaration, classInterDecl);
    lang.getScopeManager().leaveScope(recordDeclaration);
    return recordDeclaration;
}
Also used : ProblemNode(de.fraunhofer.aisec.cpg.graph.ProblemNode) ParameterizedType(de.fraunhofer.aisec.cpg.graph.types.ParameterizedType) ResolvedConstructorDeclaration(com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration) NodeList(com.github.javaparser.ast.NodeList) List(java.util.List) CompoundStatement(de.fraunhofer.aisec.cpg.graph.statements.CompoundStatement) ResolvedMethodDeclaration(com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration) RecordDeclaration(de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration) InitializerDeclaration(com.github.javaparser.ast.body.InitializerDeclaration) ClassOrInterfaceDeclaration(com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)

Aggregations

ParameterizedType (de.fraunhofer.aisec.cpg.graph.types.ParameterizedType)5 BaseTest (de.fraunhofer.aisec.cpg.BaseTest)3 ObjectType (de.fraunhofer.aisec.cpg.graph.types.ObjectType)3 Test (org.junit.jupiter.api.Test)3 NodeList (com.github.javaparser.ast.NodeList)2 ClassOrInterfaceDeclaration (com.github.javaparser.ast.body.ClassOrInterfaceDeclaration)2 InitializerDeclaration (com.github.javaparser.ast.body.InitializerDeclaration)2 ResolvedConstructorDeclaration (com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration)2 ResolvedMethodDeclaration (com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration)2 ProblemNode (de.fraunhofer.aisec.cpg.graph.ProblemNode)2 RecordDeclaration (de.fraunhofer.aisec.cpg.graph.declarations.RecordDeclaration)2 CompoundStatement (de.fraunhofer.aisec.cpg.graph.statements.CompoundStatement)2 Type (de.fraunhofer.aisec.cpg.graph.types.Type)2 UnknownType (de.fraunhofer.aisec.cpg.graph.types.UnknownType)2 List (java.util.List)2 ImportDeclaration (com.github.javaparser.ast.ImportDeclaration)1 AnnotationDeclaration (com.github.javaparser.ast.body.AnnotationDeclaration)1 AnnotationMemberDeclaration (com.github.javaparser.ast.body.AnnotationMemberDeclaration)1 BodyDeclaration (com.github.javaparser.ast.body.BodyDeclaration)1 Parameter (com.github.javaparser.ast.body.Parameter)1