mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-26 04:32:44 +01:00
2f6870edd6
Several subclasses of User override operator new without also overriding operator delete. This means that delete expressions fall back to using operator delete of the base class, which would be User. However, this is only allowed if the base class has a virtual destructor which is not the case for User, so this is UB. See also [expr.delete] (3) for the exact wording. This is actually detected in some cases by GCC 11's -Wmismatched-new-delete now which is how I found this error. Differential Revision: https://reviews.llvm.org/D103143
94 lines
3.2 KiB
C++
94 lines
3.2 KiB
C++
//===- llvm/GlobalIndirectSymbol.h - GlobalIndirectSymbol class -*- 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 contains the declaration of the GlobalIndirectSymbol class, which
|
|
// is a base class for GlobalAlias and GlobalIFunc. It contains all common code
|
|
// for aliases and ifuncs.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef LLVM_IR_GLOBALINDIRECTSYMBOL_H
|
|
#define LLVM_IR_GLOBALINDIRECTSYMBOL_H
|
|
|
|
#include "llvm/IR/GlobalObject.h"
|
|
#include "llvm/IR/GlobalValue.h"
|
|
#include "llvm/IR/OperandTraits.h"
|
|
#include "llvm/IR/User.h"
|
|
#include "llvm/IR/Value.h"
|
|
#include "llvm/Support/Casting.h"
|
|
#include <cstddef>
|
|
|
|
namespace llvm {
|
|
|
|
class GlobalIndirectSymbol : public GlobalValue {
|
|
protected:
|
|
GlobalIndirectSymbol(Type *Ty, ValueTy VTy, unsigned AddressSpace,
|
|
LinkageTypes Linkage, const Twine &Name, Constant *Symbol);
|
|
|
|
public:
|
|
GlobalIndirectSymbol(const GlobalIndirectSymbol &) = delete;
|
|
GlobalIndirectSymbol &operator=(const GlobalIndirectSymbol &) = delete;
|
|
|
|
// allocate space for exactly one operand
|
|
void *operator new(size_t S) { return User::operator new(S, 1); }
|
|
void operator delete(void *Ptr) { User::operator delete(Ptr); }
|
|
|
|
/// Provide fast operand accessors
|
|
DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Constant);
|
|
|
|
void copyAttributesFrom(const GlobalValue *Src) {
|
|
GlobalValue::copyAttributesFrom(Src);
|
|
}
|
|
|
|
/// These methods set and retrieve indirect symbol.
|
|
void setIndirectSymbol(Constant *Symbol) {
|
|
setOperand(0, Symbol);
|
|
}
|
|
const Constant *getIndirectSymbol() const {
|
|
return getOperand(0);
|
|
}
|
|
Constant *getIndirectSymbol() {
|
|
return const_cast<Constant *>(
|
|
static_cast<const GlobalIndirectSymbol *>(this)->getIndirectSymbol());
|
|
}
|
|
|
|
const GlobalObject *getBaseObject() const;
|
|
GlobalObject *getBaseObject() {
|
|
return const_cast<GlobalObject *>(
|
|
static_cast<const GlobalIndirectSymbol *>(this)->getBaseObject());
|
|
}
|
|
|
|
const GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) const {
|
|
return dyn_cast<GlobalObject>(
|
|
getIndirectSymbol()->stripAndAccumulateInBoundsConstantOffsets(DL,
|
|
Offset));
|
|
}
|
|
GlobalObject *getBaseObject(const DataLayout &DL, APInt &Offset) {
|
|
return const_cast<GlobalObject *>(
|
|
static_cast<const GlobalIndirectSymbol *>(this)
|
|
->getBaseObject(DL, Offset));
|
|
}
|
|
|
|
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
|
static bool classof(const Value *V) {
|
|
return V->getValueID() == Value::GlobalAliasVal ||
|
|
V->getValueID() == Value::GlobalIFuncVal;
|
|
}
|
|
};
|
|
|
|
template <>
|
|
struct OperandTraits<GlobalIndirectSymbol> :
|
|
public FixedNumOperandTraits<GlobalIndirectSymbol, 1> {
|
|
};
|
|
|
|
DEFINE_TRANSPARENT_OPERAND_ACCESSORS(GlobalIndirectSymbol, Constant)
|
|
|
|
} // end namespace llvm
|
|
|
|
#endif // LLVM_IR_GLOBALINDIRECTSYMBOL_H
|