// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import cpp
import semmle.code.cpp.dataflow.DataFlow
/**
* @name Use of AlignUp return value in DCHECK macro
* @description Use of the base::bits::AlignUp return value in DCHECK
* which can be problematic because there might not be enough space
* for the new aligned bytes after calling AlignUp.
* @id cpp/alignup-to-dcheck
*/
class AlignUpCall extends FunctionCall {
AlignUpCall() {
// base::bits::AlignUp call.
this.getTarget().hasQualifiedName("base::bits", "AlignUp")
}
}
module AlignUpDataFlowConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node source) {
source.asExpr() instanceof AlignUpCall
}
predicate isSink(DataFlow::Node sink) {
exists(MacroInvocation dcheckMacro |
dcheckMacro.getMacroName().regexpMatch("DCHECK_.*") and
dcheckMacro.getAGeneratedElement() = sink.asExpr()
)
}
}
module AlignUpDataFlow = DataFlow::Global<AlignUpDataFlowConfig>;
import AlignUpDataFlow::PathGraph
from AlignUpDataFlow::PathNode source, AlignUpDataFlow::PathNode sink
where AlignUpDataFlow::flowPath(source, sink)
select "base::bits::AlignUp to DCHECK", sink,
sink.getNode().getLocation().getFile().getRelativePath() + ":" +
sink.getNode().getLocation().getStartLine().toString(),
sink.getNode().asExpr().getEnclosingFunction().getDeclaringType().getTemplateArgument(0).toString()