llvm/clang/lib/Sema/JumpDiagnostics.cpp

//===--- JumpDiagnostics.cpp - Protected scope jump analysis ------*- C++ -*-=//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements the JumpScopeChecker class, which is used to diagnose
// jumps that enter a protected scope in an invalid way.
//
//===----------------------------------------------------------------------===//

#include "clang/AST/DeclCXX.h"
#include "clang/AST/Expr.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtCXX.h"
#include "clang/AST/StmtObjC.h"
#include "clang/AST/StmtOpenACC.h"
#include "clang/AST/StmtOpenMP.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Sema/SemaInternal.h"
#include "llvm/ADT/BitVector.h"
usingnamespaceclang;

namespace {

/// JumpScopeChecker - This object is used by Sema to diagnose invalid jumps
/// into VLA and other protected scopes.  For example, this rejects:
///    goto L;
///    int a[n];
///  L:
///
/// We also detect jumps out of protected scopes when it's not possible to do
/// cleanups properly. Indirect jumps and ASM jumps can't do cleanups because
/// the target is unknown. Return statements with \c [[clang::musttail]] cannot
/// handle any cleanups due to the nature of a tail call.
class JumpScopeChecker {};
} // end anonymous namespace

#define CHECK_PERMISSIVE(x)

JumpScopeChecker::JumpScopeChecker(Stmt *Body, Sema &s)
    :{}

/// GetDeepestCommonScope - Finds the innermost scope enclosing the
/// two scopes.
unsigned JumpScopeChecker::GetDeepestCommonScope(unsigned A, unsigned B) {}

ScopePair;

/// GetDiagForGotoScopeDecl - If this decl induces a new goto scope, return a
/// diagnostic that should be emitted if control goes over it. If not, return 0.
static ScopePair GetDiagForGotoScopeDecl(Sema &S, const Decl *D) {}

/// Build scope information for a declaration that is part of a DeclStmt.
void JumpScopeChecker::BuildScopeInformation(Decl *D, unsigned &ParentScope) {}

/// Build scope information for a captured block literal variables.
void JumpScopeChecker::BuildScopeInformation(VarDecl *D,
                                             const BlockDecl *BDecl,
                                             unsigned &ParentScope) {}

/// Build scope information for compound literals of C struct types that are
/// non-trivial to destruct.
void JumpScopeChecker::BuildScopeInformation(CompoundLiteralExpr *CLE,
                                             unsigned &ParentScope) {}

/// BuildScopeInformation - The statements from CI to CE are known to form a
/// coherent VLA scope with a specified parent node.  Walk through the
/// statements, adding any labels or gotos to LabelAndGotoScopes and recursively
/// walking the AST as needed.
void JumpScopeChecker::BuildScopeInformation(Stmt *S,
                                             unsigned &origParentScope) {}

/// VerifyJumps - Verify each element of the Jumps array to see if they are
/// valid, emitting diagnostics if not.
void JumpScopeChecker::VerifyJumps() {}

/// VerifyIndirectJumps - Verify whether any possible indirect goto jump might
/// cross a protection boundary.  Unlike direct jumps, indirect goto jumps
/// count cleanups as protection boundaries: since there's no way to know where
/// the jump is going, we can't implicitly run the right cleanups the way we
/// can with direct jumps.  Thus, an indirect/asm jump is "trivial" if it
/// bypasses no initializations and no teardowns.  More formally, an
/// indirect/asm jump from A to B is trivial if the path out from A to DCA(A,B)
/// is trivial and the path in from DCA(A,B) to B is trivial, where DCA(A,B) is
/// the deepest common ancestor of A and B.  Jump-triviality is transitive but
/// asymmetric.
///
/// A path in is trivial if none of the entered scopes have an InDiag.
/// A path out is trivial is none of the exited scopes have an OutDiag.
///
/// Under these definitions, this function checks that the indirect
/// jump between A and B is trivial for every indirect goto statement A
/// and every label B whose address was taken in the function.
void JumpScopeChecker::VerifyIndirectJumps() {}

/// Return true if a particular error+note combination must be downgraded to a
/// warning in Microsoft mode.
static bool IsMicrosoftJumpWarning(unsigned JumpDiag, unsigned InDiagNote) {}

/// Return true if a particular note should be downgraded to a compatibility
/// warning in C++11 mode.
static bool IsCXX98CompatWarning(Sema &S, unsigned InDiagNote) {}

/// Produce primary diagnostic for an indirect jump statement.
static void DiagnoseIndirectOrAsmJumpStmt(Sema &S, Stmt *Jump,
                                          LabelDecl *Target, bool &Diagnosed) {}

/// Produce note diagnostics for a jump into a protected scope.
void JumpScopeChecker::NoteJumpIntoScopes(ArrayRef<unsigned> ToScopes) {}

/// Diagnose an indirect jump which is known to cross scopes.
void JumpScopeChecker::DiagnoseIndirectOrAsmJump(Stmt *Jump, unsigned JumpScope,
                                                 LabelDecl *Target,
                                                 unsigned TargetScope) {}

/// CheckJump - Validate that the specified jump statement is valid: that it is
/// jumping within or out of its current scope, not into a deeper one.
void JumpScopeChecker::CheckJump(Stmt *From, Stmt *To, SourceLocation DiagLoc,
                               unsigned JumpDiagError, unsigned JumpDiagWarning,
                                 unsigned JumpDiagCXX98Compat) {}

void JumpScopeChecker::CheckGotoStmt(GotoStmt *GS) {}

void JumpScopeChecker::VerifyMustTailStmts() {}

const Attr *JumpScopeChecker::GetMustTailAttr(AttributedStmt *AS) {}

void Sema::DiagnoseInvalidJumps(Stmt *Body) {}