Skip to content

Commit 272df6c

Browse files
committed
PRE31-C: Ensure we see multiple side-effects
A macro argument can be referred to multiple times in the body of a macro without it necessarily being evaluated multiple times - for example using an expression with sizeof, type etc. To handle these cases we ensure that we see multiple equivalent side-effects.
1 parent bef5a36 commit 272df6c

File tree

1 file changed

+12
-0
lines changed

1 file changed

+12
-0
lines changed

c/cert/src/rules/PRE31-C/SideEffectsInArgumentsToUnsafeMacros.ql

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import codingstandards.cpp.SideEffect
1818
import codingstandards.cpp.StructuralEquivalence
1919
import codingstandards.cpp.sideeffect.DefaultEffects
2020
import codingstandards.cpp.sideeffect.Customizations
21+
import semmle.code.cpp.valuenumbering.HashCons
2122

2223
class FunctionCallEffect extends GlobalSideEffect::Range {
2324
FunctionCallEffect() {
@@ -100,9 +101,20 @@ where
100101
sideEffect = unsafeMacroInvocation.getSideEffectForUnsafeArg(i) and
101102
(
102103
sideEffect instanceof CrementEffect and
104+
// Do we observe the same side-effect multiple times?
105+
count(SideEffect equivalentSideEffect |
106+
equivalentSideEffect = unsafeMacroInvocation.getSideEffectForUnsafeArg(i) and
107+
hashCons(equivalentSideEffect.(CrementOperation).getOperand()) =
108+
hashCons(sideEffect.(CrementOperation).getOperand())
109+
) > 1 and
103110
sideEffectDesc = "the use of the " + sideEffect.(CrementOperation).getOperator() + " operator"
104111
or
105112
sideEffect instanceof FunctionCallEffect and
113+
// Do we observe the same side-effect multiple times?
114+
count(SideEffect equivalentSideEffect |
115+
equivalentSideEffect = unsafeMacroInvocation.getSideEffectForUnsafeArg(i) and
116+
equivalentSideEffect.(FunctionCall).getTarget() = sideEffect.(FunctionCall).getTarget()
117+
) > 1 and
106118
sideEffectDesc =
107119
"a call to the function '" + sideEffect.(FunctionCall).getTarget().getName() + "'"
108120
)

0 commit comments

Comments
 (0)