Skip to content

Commit 4fa53b6

Browse files
committed
Merge branch 'main' into destructors-for-unconditional-unnamed
2 parents 9c25ce4 + e08790d commit 4fa53b6

File tree

192 files changed

+16842
-1196
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

192 files changed

+16842
-1196
lines changed

cpp/ql/lib/semmle/code/cpp/models/Models.qll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,4 @@ private import implementations.SqLite3
4141
private import implementations.PostgreSql
4242
private import implementations.System
4343
private import implementations.StructuredExceptionHandling
44+
private import implementations.Fopen
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/**
2+
* Provides implementation classes modeling `fopen` and various similar
3+
* functions. See `semmle.code.cpp.models.Models` for usage information.
4+
*/
5+
6+
import semmle.code.cpp.models.interfaces.Alias
7+
import semmle.code.cpp.models.interfaces.SideEffect
8+
9+
/** The function `fopen` and friends. */
10+
private class Fopen extends Function, AliasFunction, SideEffectFunction {
11+
Fopen() {
12+
this.hasGlobalOrStdName(["fopen", "fopen_s", "freopen"])
13+
or
14+
this.hasGlobalName(["_open", "_wfopen", "_fsopen", "_wfsopen", "_wopen"])
15+
}
16+
17+
override predicate hasOnlySpecificWriteSideEffects() { any() }
18+
19+
override predicate hasOnlySpecificReadSideEffects() { any() }
20+
21+
override predicate parameterEscapesOnlyViaReturn(int i) { none() }
22+
23+
override predicate parameterNeverEscapes(int index) {
24+
// None of the parameters escape
25+
this.getParameter(index).getUnspecifiedType() instanceof PointerType
26+
}
27+
28+
override predicate hasSpecificReadSideEffect(ParameterIndex i, boolean buffer) {
29+
(
30+
this.hasGlobalOrStdName(["fopen", "fopen_s"])
31+
or
32+
this.hasGlobalName(["_wfopen", "_fsopen", "_wfsopen"])
33+
) and
34+
i = [0, 1] and
35+
buffer = true
36+
or
37+
this.hasGlobalOrStdName("freopen") and
38+
(
39+
i = [0, 1] and
40+
buffer = true
41+
or
42+
i = 2 and
43+
buffer = false
44+
)
45+
or
46+
this.hasGlobalName(["_open", "_wopen"]) and
47+
i = 0 and
48+
buffer = true
49+
}
50+
}

cpp/ql/test/library-tests/ir/ir/PrintAST.expected

Lines changed: 128 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -20380,126 +20380,150 @@ ir.cpp:
2038020380
# 2430| Type = [ClassTemplateInstantiation,Struct] iterator<random_access_iterator_tag, char, ptrdiff_t, char *, char &>
2038120381
# 2430| ValueCategory = lvalue
2038220382
# 2432| getStmt(6): [ReturnStmt] return ...
20383-
# 2434| [TopLevelFunction] void rethrow_with_destruction(int)
20383+
# 2434| [TopLevelFunction] void param_with_destructor_by_value(ClassWithDestructor)
2038420384
# 2434| <params>:
20385-
# 2434| getParameter(0): [Parameter] x
20386-
# 2434| Type = [IntType] int
20385+
# 2434| getParameter(0): [Parameter] c
20386+
# 2434| Type = [Class] ClassWithDestructor
2038720387
# 2434| getEntryPoint(): [BlockStmt] { ... }
20388-
# 2435| getStmt(0): [DeclStmt] declaration
20389-
# 2435| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
20390-
# 2435| Type = [Class] ClassWithDestructor
20391-
# 2435| getVariable().getInitializer(): [Initializer] initializer for c
20392-
# 2435| getExpr(): [ConstructorCall] call to ClassWithDestructor
20393-
# 2435| Type = [VoidType] void
20394-
# 2435| ValueCategory = prvalue
20395-
# 2436| getStmt(1): [ExprStmt] ExprStmt
20396-
# 2436| getExpr(): [ReThrowExpr] re-throw exception
20397-
# 2436| Type = [VoidType] void
20398-
# 2436| ValueCategory = prvalue
20399-
# 2437| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
20400-
# 2437| Type = [VoidType] void
20401-
# 2437| ValueCategory = prvalue
20402-
# 2437| getQualifier(): [VariableAccess] c
20403-
# 2437| Type = [Class] ClassWithDestructor
20404-
# 2437| ValueCategory = lvalue
20405-
# 2439| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&)
20406-
# 2439| <params>:
20388+
# 2436| getStmt(0): [ReturnStmt] return ...
20389+
# 2438| [TopLevelFunction] void param_with_destructor_by_pointer(ClassWithDestructor*)
20390+
# 2438| <params>:
20391+
# 2438| getParameter(0): [Parameter] c
20392+
# 2438| Type = [PointerType] ClassWithDestructor *
20393+
# 2438| getEntryPoint(): [BlockStmt] { ... }
20394+
# 2440| getStmt(0): [ReturnStmt] return ...
20395+
# 2442| [TopLevelFunction] void param_with_destructor_by_ref(ClassWithDestructor&)
20396+
# 2442| <params>:
20397+
# 2442| getParameter(0): [Parameter] c
20398+
# 2442| Type = [LValueReferenceType] ClassWithDestructor &
20399+
# 2442| getEntryPoint(): [BlockStmt] { ... }
20400+
# 2444| getStmt(0): [ReturnStmt] return ...
20401+
# 2446| [TopLevelFunction] void param_with_destructor_by_rref(ClassWithDestructor&&)
20402+
# 2446| <params>:
20403+
# 2446| getParameter(0): [Parameter] c
20404+
# 2446| Type = [RValueReferenceType] ClassWithDestructor &&
20405+
# 2446| getEntryPoint(): [BlockStmt] { ... }
20406+
# 2448| getStmt(0): [ReturnStmt] return ...
20407+
# 2450| [TopLevelFunction] void rethrow_with_destruction(int)
20408+
# 2450| <params>:
20409+
# 2450| getParameter(0): [Parameter] x
20410+
# 2450| Type = [IntType] int
20411+
# 2450| getEntryPoint(): [BlockStmt] { ... }
20412+
# 2451| getStmt(0): [DeclStmt] declaration
20413+
# 2451| getDeclarationEntry(0): [VariableDeclarationEntry] definition of c
20414+
# 2451| Type = [Class] ClassWithDestructor
20415+
# 2451| getVariable().getInitializer(): [Initializer] initializer for c
20416+
# 2451| getExpr(): [ConstructorCall] call to ClassWithDestructor
20417+
# 2451| Type = [VoidType] void
20418+
# 2451| ValueCategory = prvalue
20419+
# 2452| getStmt(1): [ExprStmt] ExprStmt
20420+
# 2452| getExpr(): [ReThrowExpr] re-throw exception
20421+
# 2452| Type = [VoidType] void
20422+
# 2452| ValueCategory = prvalue
20423+
# 2453| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
20424+
# 2453| Type = [VoidType] void
20425+
# 2453| ValueCategory = prvalue
20426+
# 2453| getQualifier(): [VariableAccess] c
20427+
# 2453| Type = [Class] ClassWithDestructor
20428+
# 2453| ValueCategory = lvalue
20429+
# 2455| [CopyAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor const&)
20430+
# 2455| <params>:
2040720431
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2040820432
#-----| Type = [LValueReferenceType] const ByValueConstructor &
20409-
# 2439| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&)
20410-
# 2439| <params>:
20433+
# 2455| [MoveAssignmentOperator] ByValueConstructor& ByValueConstructor::operator=(ByValueConstructor&&)
20434+
# 2455| <params>:
2041120435
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2041220436
#-----| Type = [RValueReferenceType] ByValueConstructor &&
20413-
# 2439| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&)
20414-
# 2439| <params>:
20437+
# 2455| [CopyConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor const&)
20438+
# 2455| <params>:
2041520439
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2041620440
#-----| Type = [LValueReferenceType] const ByValueConstructor &
20417-
# 2439| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&)
20418-
# 2439| <params>:
20441+
# 2455| [MoveConstructor] void ByValueConstructor::ByValueConstructor(ByValueConstructor&&)
20442+
# 2455| <params>:
2041920443
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2042020444
#-----| Type = [RValueReferenceType] ByValueConstructor &&
20421-
# 2440| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor)
20422-
# 2440| <params>:
20423-
# 2440| getParameter(0): [Parameter] (unnamed parameter 0)
20424-
# 2440| Type = [Class] ClassWithDestructor
20425-
# 2443| [TopLevelFunction] void new_with_destructor(ClassWithDestructor)
20426-
# 2443| <params>:
20427-
# 2443| getParameter(0): [Parameter] a
20428-
# 2443| Type = [Class] ClassWithDestructor
20429-
# 2444| getEntryPoint(): [BlockStmt] { ... }
20430-
# 2445| getStmt(0): [DeclStmt] declaration
20431-
# 2445| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
20432-
# 2445| Type = [PointerType] ByValueConstructor *
20433-
# 2445| getVariable().getInitializer(): [Initializer] initializer for b
20434-
# 2445| getExpr(): [NewExpr] new
20435-
# 2445| Type = [PointerType] ByValueConstructor *
20436-
# 2445| ValueCategory = prvalue
20437-
# 2445| getInitializer(): [ConstructorCall] call to ByValueConstructor
20438-
# 2445| Type = [VoidType] void
20439-
# 2445| ValueCategory = prvalue
20440-
# 2445| getArgument(0): [VariableAccess] a
20441-
# 2445| Type = [Class] ClassWithDestructor
20442-
# 2445| ValueCategory = prvalue(load)
20443-
# 2445| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object
20444-
# 2445| Type = [Class] ClassWithDestructor
20445-
# 2445| ValueCategory = lvalue
20446-
# 2445| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
20447-
# 2445| Type = [VoidType] void
20448-
# 2445| ValueCategory = prvalue
20449-
# 2445| getQualifier(): [ReuseExpr] reuse of temporary object
20450-
# 2445| Type = [Class] ClassWithDestructor
20451-
# 2445| ValueCategory = xvalue
20452-
# 2446| getStmt(1): [ReturnStmt] return ...
20453-
# 2449| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&)
20454-
# 2449| <params>:
20445+
# 2456| [Constructor] void ByValueConstructor::ByValueConstructor(ClassWithDestructor)
20446+
# 2456| <params>:
20447+
# 2456| getParameter(0): [Parameter] (unnamed parameter 0)
20448+
# 2456| Type = [Class] ClassWithDestructor
20449+
# 2459| [TopLevelFunction] void new_with_destructor(ClassWithDestructor)
20450+
# 2459| <params>:
20451+
# 2459| getParameter(0): [Parameter] a
20452+
# 2459| Type = [Class] ClassWithDestructor
20453+
# 2460| getEntryPoint(): [BlockStmt] { ... }
20454+
# 2461| getStmt(0): [DeclStmt] declaration
20455+
# 2461| getDeclarationEntry(0): [VariableDeclarationEntry] definition of b
20456+
# 2461| Type = [PointerType] ByValueConstructor *
20457+
# 2461| getVariable().getInitializer(): [Initializer] initializer for b
20458+
# 2461| getExpr(): [NewExpr] new
20459+
# 2461| Type = [PointerType] ByValueConstructor *
20460+
# 2461| ValueCategory = prvalue
20461+
# 2461| getInitializer(): [ConstructorCall] call to ByValueConstructor
20462+
# 2461| Type = [VoidType] void
20463+
# 2461| ValueCategory = prvalue
20464+
# 2461| getArgument(0): [VariableAccess] a
20465+
# 2461| Type = [Class] ClassWithDestructor
20466+
# 2461| ValueCategory = prvalue(load)
20467+
# 2461| getArgument(0).getFullyConverted(): [TemporaryObjectExpr] temporary object
20468+
# 2461| Type = [Class] ClassWithDestructor
20469+
# 2461| ValueCategory = lvalue
20470+
# 2461| getImplicitDestructorCall(0): [DestructorCall] call to ~ClassWithDestructor
20471+
# 2461| Type = [VoidType] void
20472+
# 2461| ValueCategory = prvalue
20473+
# 2461| getQualifier(): [ReuseExpr] reuse of temporary object
20474+
# 2461| Type = [Class] ClassWithDestructor
20475+
# 2461| ValueCategory = xvalue
20476+
# 2462| getStmt(1): [ReturnStmt] return ...
20477+
# 2465| [CopyAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A const&)
20478+
# 2465| <params>:
2045520479
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2045620480
#-----| Type = [LValueReferenceType] const A &
20457-
# 2449| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&)
20458-
# 2449| <params>:
20481+
# 2465| [MoveAssignmentOperator] rvalue_conversion_with_destructor::A& rvalue_conversion_with_destructor::A::operator=(rvalue_conversion_with_destructor::A&&)
20482+
# 2465| <params>:
2045920483
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2046020484
#-----| Type = [RValueReferenceType] A &&
20461-
# 2453| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&)
20462-
# 2453| <params>:
20485+
# 2469| [CopyAssignmentOperator] rvalue_conversion_with_destructor::B& rvalue_conversion_with_destructor::B::operator=(rvalue_conversion_with_destructor::B const&)
20486+
# 2469| <params>:
2046320487
#-----| getParameter(0): [Parameter] (unnamed parameter 0)
2046420488
#-----| Type = [LValueReferenceType] const B &
20465-
# 2453| [Constructor] void rvalue_conversion_with_destructor::B::B()
20466-
# 2453| <params>:
20467-
# 2455| [Destructor] void rvalue_conversion_with_destructor::B::~B()
20468-
# 2455| <params>:
20469-
# 2457| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const
20470-
# 2457| <params>:
20471-
# 2460| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get()
20472-
# 2460| <params>:
20473-
# 2462| [TopLevelFunction] void rvalue_conversion_with_destructor::test()
20474-
# 2462| <params>:
20475-
# 2463| getEntryPoint(): [BlockStmt] { ... }
20476-
# 2464| getStmt(0): [DeclStmt] declaration
20477-
# 2464| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
20478-
# 2464| Type = [IntType] unsigned int
20479-
# 2464| getVariable().getInitializer(): [Initializer] initializer for a
20480-
# 2464| getExpr(): [PointerFieldAccess] a
20481-
# 2464| Type = [IntType] unsigned int
20482-
# 2464| ValueCategory = prvalue(load)
20483-
# 2464| getQualifier(): [FunctionCall] call to operator->
20484-
# 2464| Type = [PointerType] A *
20485-
# 2464| ValueCategory = prvalue
20486-
# 2464| getQualifier(): [FunctionCall] call to get
20487-
# 2464| Type = [Struct] B
20488-
# 2464| ValueCategory = prvalue
20489-
# 2464| getQualifier().getFullyConverted(): [CStyleCast] (const B)...
20490-
# 2464| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion
20491-
# 2464| Type = [SpecifiedType] const B
20492-
# 2464| ValueCategory = prvalue
20493-
# 2464| getExpr(): [TemporaryObjectExpr] temporary object
20494-
# 2464| Type = [Struct] B
20495-
# 2464| ValueCategory = prvalue(load)
20496-
# 2464| getImplicitDestructorCall(0): [DestructorCall] call to ~B
20497-
# 2464| Type = [VoidType] void
20498-
# 2464| ValueCategory = prvalue
20499-
# 2464| getQualifier(): [ReuseExpr] reuse of temporary object
20500-
# 2464| Type = [Struct] B
20501-
# 2464| ValueCategory = xvalue
20502-
# 2465| getStmt(1): [ReturnStmt] return ...
20489+
# 2469| [Constructor] void rvalue_conversion_with_destructor::B::B()
20490+
# 2469| <params>:
20491+
# 2471| [Destructor] void rvalue_conversion_with_destructor::B::~B()
20492+
# 2471| <params>:
20493+
# 2473| [ConstMemberFunction] rvalue_conversion_with_destructor::A* rvalue_conversion_with_destructor::B::operator->() const
20494+
# 2473| <params>:
20495+
# 2476| [TopLevelFunction] rvalue_conversion_with_destructor::B rvalue_conversion_with_destructor::get()
20496+
# 2476| <params>:
20497+
# 2478| [TopLevelFunction] void rvalue_conversion_with_destructor::test()
20498+
# 2478| <params>:
20499+
# 2479| getEntryPoint(): [BlockStmt] { ... }
20500+
# 2480| getStmt(0): [DeclStmt] declaration
20501+
# 2480| getDeclarationEntry(0): [VariableDeclarationEntry] definition of a
20502+
# 2480| Type = [IntType] unsigned int
20503+
# 2480| getVariable().getInitializer(): [Initializer] initializer for a
20504+
# 2480| getExpr(): [PointerFieldAccess] a
20505+
# 2480| Type = [IntType] unsigned int
20506+
# 2480| ValueCategory = prvalue(load)
20507+
# 2480| getQualifier(): [FunctionCall] call to operator->
20508+
# 2480| Type = [PointerType] A *
20509+
# 2480| ValueCategory = prvalue
20510+
# 2480| getQualifier(): [FunctionCall] call to get
20511+
# 2480| Type = [Struct] B
20512+
# 2480| ValueCategory = prvalue
20513+
# 2480| getQualifier().getFullyConverted(): [CStyleCast] (const B)...
20514+
# 2480| Conversion = [PrvalueAdjustmentConversion] prvalue adjustment conversion
20515+
# 2480| Type = [SpecifiedType] const B
20516+
# 2480| ValueCategory = prvalue
20517+
# 2480| getExpr(): [TemporaryObjectExpr] temporary object
20518+
# 2480| Type = [Struct] B
20519+
# 2480| ValueCategory = prvalue(load)
20520+
# 2480| getImplicitDestructorCall(0): [DestructorCall] call to ~B
20521+
# 2480| Type = [VoidType] void
20522+
# 2480| ValueCategory = prvalue
20523+
# 2480| getQualifier(): [ReuseExpr] reuse of temporary object
20524+
# 2480| Type = [Struct] B
20525+
# 2480| ValueCategory = xvalue
20526+
# 2481| getStmt(1): [ReturnStmt] return ...
2050320527
perf-regression.cpp:
2050420528
# 4| [CopyAssignmentOperator] Big& Big::operator=(Big const&)
2050520529
# 4| <params>:

0 commit comments

Comments
 (0)