@@ -182,6 +182,8 @@ class PrintASTNode extends TPrintASTNode {
182182 result = childIndex .toString ( )
183183 }
184184
185+ abstract string getChildAccessorPredicate ( int childIndex ) ;
186+
185187 /**
186188 * Gets the label for the edge from this node to the specified child,
187189 * including labels for edges to nodes that represent conversions.
@@ -261,6 +263,10 @@ class ExprNode extends ASTNode {
261263 result = expr .getValueCategoryString ( )
262264 }
263265
266+ override string getChildAccessorPredicate ( int childIndex ) {
267+ result = getChildAccessor ( ast , getChildInternal ( childIndex ) .getAST ( ) )
268+ }
269+
264270 /**
265271 * Gets the value of this expression, if it is a constant.
266272 */
@@ -322,6 +328,8 @@ class DeclarationEntryNode extends BaseASTNode, TDeclarationEntryNode {
322328
323329 override PrintASTNode getChildInternal ( int childIndex ) { none ( ) }
324330
331+ override string getChildAccessorPredicate ( int childIndex ) { none ( ) }
332+
325333 override string getProperty ( string key ) {
326334 result = BaseASTNode .super .getProperty ( key )
327335 or
@@ -341,6 +349,11 @@ class VariableDeclarationEntryNode extends DeclarationEntryNode {
341349 result .getAST ( ) = ast .getVariable ( ) .getInitializer ( )
342350 }
343351
352+ override string getChildAccessorPredicate ( int childIndex ) {
353+ childIndex = 0 and
354+ result = "getVariable().getInitializer()"
355+ }
356+
344357 override string getChildEdgeLabelInternal ( int childIndex ) { childIndex = 0 and result = "init" }
345358}
346359
@@ -361,6 +374,10 @@ class StmtNode extends ASTNode {
361374 )
362375 )
363376 }
377+
378+ override string getChildAccessorPredicate ( int childIndex ) {
379+ result = getChildAccessor ( ast , getChildInternal ( childIndex ) .getAST ( ) )
380+ }
364381}
365382
366383/**
@@ -389,6 +406,8 @@ class ParameterNode extends ASTNode {
389406
390407 final override PrintASTNode getChildInternal ( int childIndex ) { none ( ) }
391408
409+ final override string getChildAccessorPredicate ( int childIndex ) { none ( ) }
410+
392411 final override string getProperty ( string key ) {
393412 result = super .getProperty ( key )
394413 or
@@ -410,6 +429,11 @@ class InitializerNode extends ASTNode {
410429 result .getAST ( ) = init .getExpr ( )
411430 }
412431
432+ override string getChildAccessorPredicate ( int childIndex ) {
433+ childIndex = 0 and
434+ result = "getExpr()"
435+ }
436+
413437 override string getChildEdgeLabelInternal ( int childIndex ) {
414438 childIndex = 0 and
415439 result = "expr"
@@ -432,6 +456,11 @@ class ParametersNode extends PrintASTNode, TParametersNode {
432456 result .getAST ( ) = func .getParameter ( childIndex )
433457 }
434458
459+ override string getChildAccessorPredicate ( int childIndex ) {
460+ exists ( getChild ( childIndex ) ) and
461+ result = "getParameter(" + childIndex .toString ( ) + ")"
462+ }
463+
435464 /**
436465 * Gets the `Function` for which this node represents the parameters.
437466 */
@@ -454,6 +483,11 @@ class ConstructorInitializersNode extends PrintASTNode, TConstructorInitializers
454483 result .getAST ( ) = ctor .getInitializer ( childIndex )
455484 }
456485
486+ final override string getChildAccessorPredicate ( int childIndex ) {
487+ exists ( getChild ( childIndex ) ) and
488+ result = "getInitializer(" + childIndex .toString ( ) + ")"
489+ }
490+
457491 /**
458492 * Gets the `Constructor` for which this node represents the initializer list.
459493 */
@@ -476,6 +510,11 @@ class DestructorDestructionsNode extends PrintASTNode, TDestructorDestructionsNo
476510 result .getAST ( ) = dtor .getDestruction ( childIndex )
477511 }
478512
513+ final override string getChildAccessorPredicate ( int childIndex ) {
514+ exists ( getChild ( childIndex ) ) and
515+ result = "getDestruction(" + childIndex .toString ( ) + ")"
516+ }
517+
479518 /**
480519 * Gets the `Destructor` for which this node represents the destruction list.
481520 */
@@ -506,6 +545,20 @@ class FunctionNode extends ASTNode {
506545 result .( DestructorDestructionsNode ) .getDestructor ( ) = func
507546 }
508547
548+ override string getChildAccessorPredicate ( int childIndex ) {
549+ childIndex = 0 and
550+ result = "..."
551+ or
552+ childIndex = 1 and
553+ result = "..."
554+ or
555+ childIndex = 2 and
556+ result = "getEntryPoint()"
557+ or
558+ childIndex = 3 and
559+ result = "..."
560+ }
561+
509562 override string getChildEdgeLabelInternal ( int childIndex ) {
510563 childIndex = 0 and result = "params"
511564 or
@@ -570,6 +623,239 @@ class ArrayAggregateLiteralNode extends ExprNode {
570623 }
571624}
572625
626+ string getChildAccessor ( Locatable parent , Element child ) {
627+ shouldPrintFunction ( getEnclosingFunction ( parent ) ) and
628+ (
629+ exists ( Stmt s | s = parent .( Stmt ) |
630+ namedStmtChildPredicates ( s , child , result )
631+ or
632+ not exists ( string p | namedStmtChildPredicates ( s , child , p ) ) and
633+ exists ( int n | s .getChild ( n ) = child and result = "getChild(" + n + ")" )
634+ )
635+ or
636+ exists ( Expr expr | expr = parent .( Expr ) |
637+ namedExprChildPredicates ( expr , child , result )
638+ or
639+ not exists ( string p | namedExprChildPredicates ( expr , child , p ) ) and
640+ exists ( int n | expr .getChild ( n ) = child and result = "getChild(" + n + ")" )
641+ )
642+ )
643+ }
644+
645+ predicate namedStmtChildPredicates ( Locatable s , Element e , string pred ) {
646+ shouldPrintFunction ( getEnclosingFunction ( s ) ) and
647+ (
648+ exists ( int n | s .( BlockStmt ) .getStmt ( n ) = e and pred = "getStmt(" + n + ")" )
649+ or
650+ s .( ComputedGotoStmt ) .getExpr ( ) = e and pred = "getExpr()"
651+ or
652+ s .( ConstexprIfStmt ) .getCondition ( ) = e and pred = "getCondition()"
653+ or
654+ s .( ConstexprIfStmt ) .getThen ( ) = e and pred = "getThen()"
655+ or
656+ s .( ConstexprIfStmt ) .getElse ( ) = e and pred = "getElse()"
657+ or
658+ s .( IfStmt ) .getCondition ( ) = e and pred = "getCondition()"
659+ or
660+ s .( IfStmt ) .getThen ( ) = e and pred = "getThen()"
661+ or
662+ s .( IfStmt ) .getElse ( ) = e and pred = "getElse()"
663+ or
664+ s .( SwitchStmt ) .getExpr ( ) = e and pred = "getExpr()"
665+ or
666+ s .( SwitchStmt ) .getStmt ( ) = e and pred = "getStmt()"
667+ or
668+ s .( DoStmt ) .getCondition ( ) = e and pred = "getCondition()"
669+ or
670+ s .( DoStmt ) .getStmt ( ) = e and pred = "getStmt()"
671+ or
672+ s .( ForStmt ) .getInitialization ( ) = e and pred = "getInitialization()"
673+ or
674+ s .( ForStmt ) .getCondition ( ) = e and pred = "getCondition()"
675+ or
676+ s .( ForStmt ) .getUpdate ( ) = e and pred = "getUpdate()"
677+ or
678+ s .( ForStmt ) .getStmt ( ) = e and pred = "getStmt()"
679+ or
680+ s .( RangeBasedForStmt ) .getChild ( 0 ) = e and pred = "getChild(0)" // TODO: could be omitted
681+ or
682+ s .( RangeBasedForStmt ) .getBeginEndDeclaration ( ) = e and pred = "getBeginEndDeclaration()"
683+ or
684+ s .( RangeBasedForStmt ) .getCondition ( ) = e and pred = "getCondition()"
685+ or
686+ s .( RangeBasedForStmt ) .getUpdate ( ) = e and pred = "getUpdate()"
687+ or
688+ s .( RangeBasedForStmt ) .getChild ( 4 ) = e and pred = "getChild(4)" // TODO: could be omitted
689+ or
690+ s .( RangeBasedForStmt ) .getStmt ( ) = e and pred = "getStmt()"
691+ or
692+ s .( WhileStmt ) .getCondition ( ) = e and pred = "getCondition()"
693+ or
694+ s .( WhileStmt ) .getStmt ( ) = e and pred = "getStmt()"
695+ or
696+ exists ( int n |
697+ s .( DeclStmt ) .getDeclarationEntry ( n ) = e and pred = "getDeclarationEntry(" + n .toString ( ) + ")"
698+ )
699+ or
700+ // EmptyStmt does not have children
701+ s .( ExprStmt ) .getExpr ( ) = e and pred = "getExpr()"
702+ or
703+ s .( Handler ) .getBlock ( ) = e and pred = "getBlock()"
704+ or
705+ s .( JumpStmt ) .getTarget ( ) = e and pred = "getTarget()"
706+ or
707+ s .( MicrosoftTryStmt ) .getStmt ( ) = e and pred = "getStmt()"
708+ or
709+ s .( MicrosoftTryExceptStmt ) .getCondition ( ) = e and pred = "getCondition()"
710+ or
711+ s .( MicrosoftTryExceptStmt ) .getExcept ( ) = e and pred = "getExcept()"
712+ or
713+ s .( MicrosoftTryFinallyStmt ) .getFinally ( ) = e and pred = "getFinally()"
714+ or
715+ s .( ReturnStmt ) .getExpr ( ) = e and pred = "getExpr()"
716+ or
717+ s .( SwitchCase ) .getExpr ( ) = e and pred = "getExpr()"
718+ or
719+ s .( SwitchCase ) .getEndExpr ( ) = e and pred = "getEndExpr()"
720+ or
721+ s .( TryStmt ) .getStmt ( ) = e and pred = "getStmt()"
722+ or
723+ s .( VlaDimensionStmt ) .getDimensionExpr ( ) = e and pred = "getDimensionExpr()"
724+ )
725+ }
726+
727+ predicate namedExprChildPredicates ( Expr expr , Element ele , string pred ) {
728+ shouldPrintFunction ( expr .getEnclosingFunction ( ) ) and
729+ (
730+ expr .( Access ) .getTarget ( ) = ele and pred = "getTarget()"
731+ or
732+ expr .( VariableAccess ) .getQualifier ( ) = ele and pred = "getQualifier()"
733+ or
734+ exists ( Field f |
735+ expr .( ClassAggregateLiteral ) .getFieldExpr ( f ) = ele and
736+ pred = "getFieldExpr(" + f .toString ( ) + ")"
737+ )
738+ or
739+ exists ( int n |
740+ expr .( ArrayOrVectorAggregateLiteral ) .getElementExpr ( n ) = ele and
741+ pred = "getElementExpr(" + n .toString ( ) + ")"
742+ )
743+ or
744+ expr .( AlignofExprOperator ) .getExprOperand ( ) = ele and pred = "getExprOperand()"
745+ or
746+ expr .( ArrayExpr ) .getArrayBase ( ) = ele and pred = "getArrayBase()"
747+ or
748+ expr .( ArrayExpr ) .getArrayOffset ( ) = ele and pred = "getArrayOffset()"
749+ or
750+ expr .( AssumeExpr ) .getOperand ( ) = ele and pred = "getOperand()"
751+ or
752+ expr .( BuiltInComplexOperation ) .getRealOperand ( ) = ele and pred = "getRealOperand()"
753+ or
754+ expr .( BuiltInComplexOperation ) .getImaginaryOperand ( ) = ele and pred = "getImaginaryOperand()"
755+ or
756+ expr .( BuiltInVarArg ) .getVAList ( ) = ele and pred = "getVAList()"
757+ or
758+ expr .( BuiltInVarArgCopy ) .getDestinationVAList ( ) = ele and pred = "getDestinationVAList()"
759+ or
760+ expr .( BuiltInVarArgCopy ) .getSourceVAList ( ) = ele and pred = "getSourceVAList()"
761+ or
762+ expr .( BuiltInVarArgsEnd ) .getVAList ( ) = ele and pred = "getVAList()"
763+ or
764+ expr .( BuiltInVarArgsStart ) .getVAList ( ) = ele and pred = "getVAList()"
765+ or
766+ expr .( BuiltInVarArgsStart ) .getLastNamedParameter ( ) = ele and pred = "getLastNamedParameter()"
767+ or
768+ expr .( Call ) .getQualifier ( ) = ele and pred = "getQualifier()"
769+ or
770+ exists ( int n | expr .( Call ) .getArgument ( n ) = ele and pred = "getArgument(" + n .toString ( ) + ")" )
771+ or
772+ expr .( ExprCall ) .getExpr ( ) = ele and pred = "getExpr()"
773+ or
774+ expr .( OverloadedArrayExpr ) .getArrayBase ( ) = ele and pred = "getArrayBase()"
775+ or
776+ expr .( OverloadedArrayExpr ) .getArrayOffset ( ) = ele and pred = "getArrayOffset()"
777+ or
778+ expr .( OverloadedPointerDereferenceExpr ) .getExpr ( ) = ele and pred = "getExpr()"
779+ or
780+ expr .( CommaExpr ) .getLeftOperand ( ) = ele and pred = "getLeftOperand()"
781+ or
782+ expr .( CommaExpr ) .getRightOperand ( ) = ele and pred = "getRightOperand()"
783+ or
784+ expr .( ConditionDeclExpr ) .getVariableAccess ( ) = ele and pred = "getVariableAccess()"
785+ or
786+ expr .( ConstructorFieldInit ) .getExpr ( ) = ele and pred = "getExpr()"
787+ or
788+ expr .( Conversion ) .getExpr ( ) = ele and pred = "getExpr()"
789+ or
790+ expr .( DeleteArrayExpr ) .getAllocatorCall ( ) = ele and pred = "getAllocatorCall()"
791+ or
792+ expr .( DeleteArrayExpr ) .getDestructorCall ( ) = ele and pred = "getDestructorCall()"
793+ or
794+ expr .( DeleteArrayExpr ) .getExpr ( ) = ele and pred = "getExpr()"
795+ or
796+ expr .( DeleteExpr ) .getAllocatorCall ( ) = ele and pred = "getAllocatorCall()"
797+ or
798+ expr .( DeleteExpr ) .getDestructorCall ( ) = ele and pred = "getDestructorCall()"
799+ or
800+ expr .( DeleteExpr ) .getExpr ( ) = ele and pred = "getExpr()"
801+ or
802+ expr .( DestructorFieldDestruction ) .getExpr ( ) = ele and pred = "getExpr()"
803+ or
804+ expr .( FoldExpr ) .getInitExpr ( ) = ele and pred = "getInitExpr()"
805+ or
806+ expr .( FoldExpr ) .getPackExpr ( ) = ele and pred = "getPackExpr()"
807+ or
808+ expr .( LambdaExpression ) .getInitializer ( ) = ele and pred = "getInitializer()"
809+ or
810+ expr .( NewOrNewArrayExpr ) .getAllocatorCall ( ) = ele and pred = "getAllocatorCall()"
811+ or
812+ expr .( NewOrNewArrayExpr ) .getAlignmentArgument ( ) = ele and pred = "getAlignmentArgument()"
813+ or
814+ expr .( NewArrayExpr ) .getInitializer ( ) = ele and pred = "getInitializer()"
815+ or
816+ expr .( NewArrayExpr ) .getExtent ( ) = ele and pred = "getExtent()"
817+ or
818+ expr .( NewExpr ) .getInitializer ( ) = ele and pred = "getInitializer()"
819+ or
820+ expr .( NoExceptExpr ) .getExpr ( ) = ele and pred = "getExpr()"
821+ or
822+ expr .( Assignment ) .getLValue ( ) = ele and pred = "getLValue()"
823+ or
824+ expr .( Assignment ) .getRValue ( ) = ele and pred = "getRValue()"
825+ or
826+ not expr instanceof RelationalOperation and
827+ expr .( BinaryOperation ) .getLeftOperand ( ) = ele and
828+ pred = "getLeftOperand()"
829+ or
830+ not expr instanceof RelationalOperation and
831+ expr .( BinaryOperation ) .getRightOperand ( ) = ele and
832+ pred = "getRightOperand()"
833+ or
834+ expr .( RelationalOperation ) .getGreaterOperand ( ) = ele and pred = "getGreaterOperand()"
835+ or
836+ expr .( RelationalOperation ) .getLesserOperand ( ) = ele and pred = "getLesserOperand()"
837+ or
838+ expr .( ConditionalExpr ) .getCondition ( ) = ele and pred = "getCondition()"
839+ or
840+ // If ConditionalExpr is in two-operand form, getThen() = getCondition() holds
841+ not expr .( ConditionalExpr ) .isTwoOperand ( ) and
842+ expr .( ConditionalExpr ) .getThen ( ) = ele and
843+ pred = "getThen()"
844+ or
845+ expr .( ConditionalExpr ) .getElse ( ) = ele and pred = "getElse()"
846+ or
847+ expr .( UnaryOperation ) .getOperand ( ) = ele and pred = "getOperand()"
848+ or
849+ expr .( SizeofExprOperator ) .getExprOperand ( ) = ele and pred = "getExprOperand()"
850+ or
851+ //expr.(StmtExpr).getStmt() = ele and pred = "getStmt()" // TODO confirm via test that this is a/the child
852+ //or
853+ expr .( ThrowExpr ) .getExpr ( ) = ele and pred = "getExpr()"
854+ or
855+ expr .( TypeidOperator ) .getExpr ( ) = ele and pred = "getExpr()"
856+ )
857+ }
858+
573859/** Holds if `node` belongs to the output tree, and its property `key` has the given `value`. */
574860query predicate nodes ( PrintASTNode node , string key , string value ) {
575861 node .shouldPrint ( ) and
@@ -586,9 +872,12 @@ query predicate edges(PrintASTNode source, PrintASTNode target, string key, stri
586872 target .shouldPrint ( ) and
587873 target = source .getChild ( childIndex ) and
588874 (
589- key = "semmle.label" and value = source .getChildEdgeLabel ( childIndex )
875+ key = "semmle.label" and value = source .getChildAccessorPredicate ( childIndex ) //source. getChildEdgeLabel(childIndex)
590876 or
591877 key = "semmle.order" and value = childIndex .toString ( )
878+ or
879+ key = "semmle.predicate" and
880+ value = source .getChildAccessorPredicate ( childIndex )
592881 )
593882 )
594883}
0 commit comments