Allow passing a location to BroObj::Warning and BroObj::Error.

This allows callers (such as check_and_promote) to pass an expression location to be logged if the location doesn't exist in the value being promoted.
This commit is contained in:
Tim Wojtulewicz 2019-05-30 15:36:30 -07:00
parent 8ca2cff13f
commit 2d61ea5cd6
4 changed files with 16 additions and 14 deletions

View file

@ -100,21 +100,21 @@ BroObj::~BroObj()
delete location; delete location;
} }
void BroObj::Warn(const char* msg, const BroObj* obj2, int pinpoint_only) const void BroObj::Warn(const char* msg, const BroObj* obj2, int pinpoint_only, const Location* expr_location) const
{ {
ODesc d; ODesc d;
DoMsg(&d, msg, obj2, pinpoint_only); DoMsg(&d, msg, obj2, pinpoint_only, expr_location);
reporter->Warning("%s", d.Description()); reporter->Warning("%s", d.Description());
reporter->PopLocation(); reporter->PopLocation();
} }
void BroObj::Error(const char* msg, const BroObj* obj2, int pinpoint_only) const void BroObj::Error(const char* msg, const BroObj* obj2, int pinpoint_only, const Location* expr_location) const
{ {
if ( suppress_errors ) if ( suppress_errors )
return; return;
ODesc d; ODesc d;
DoMsg(&d, msg, obj2, pinpoint_only); DoMsg(&d, msg, obj2, pinpoint_only, expr_location);
reporter->Error("%s", d.Description()); reporter->Error("%s", d.Description());
reporter->PopLocation(); reporter->PopLocation();
} }
@ -200,7 +200,7 @@ void BroObj::UpdateLocationEndInfo(const Location& end)
} }
void BroObj::DoMsg(ODesc* d, const char s1[], const BroObj* obj2, void BroObj::DoMsg(ODesc* d, const char s1[], const BroObj* obj2,
int pinpoint_only) const int pinpoint_only, const Location* expr_location) const
{ {
d->SetShort(); d->SetShort();
@ -211,6 +211,8 @@ void BroObj::DoMsg(ODesc* d, const char s1[], const BroObj* obj2,
if ( obj2 && obj2->GetLocationInfo() != &no_location && if ( obj2 && obj2->GetLocationInfo() != &no_location &&
*obj2->GetLocationInfo() != *GetLocationInfo() ) *obj2->GetLocationInfo() != *GetLocationInfo() )
loc2 = obj2->GetLocationInfo(); loc2 = obj2->GetLocationInfo();
else if ( expr_location )
loc2 = expr_location;
reporter->PushLocation(GetLocationInfo(), loc2); reporter->PushLocation(GetLocationInfo(), loc2);
} }

View file

@ -118,9 +118,9 @@ public:
// included in the message, though if pinpoint_only is non-zero, // included in the message, though if pinpoint_only is non-zero,
// then obj2 is only used to pinpoint the location. // then obj2 is only used to pinpoint the location.
void Warn(const char* msg, const BroObj* obj2 = 0, void Warn(const char* msg, const BroObj* obj2 = 0,
int pinpoint_only = 0) const; int pinpoint_only = 0, const Location* expr_location = 0) const;
void Error(const char* msg, const BroObj* obj2 = 0, void Error(const char* msg, const BroObj* obj2 = 0,
int pinpoint_only = 0) const; int pinpoint_only = 0, const Location* expr_location = 0) const;
// Report internal errors. // Report internal errors.
void BadTag(const char* msg, const char* t1 = 0, void BadTag(const char* msg, const char* t1 = 0,
@ -178,7 +178,7 @@ private:
friend class SuppressErrors; friend class SuppressErrors;
void DoMsg(ODesc* d, const char s1[], const BroObj* obj2 = 0, void DoMsg(ODesc* d, const char s1[], const BroObj* obj2 = 0,
int pinpoint_only = 0) const; int pinpoint_only = 0, const Location* expr_location = 0) const;
void PinPoint(ODesc* d, const BroObj* obj2 = 0, void PinPoint(ODesc* d, const BroObj* obj2 = 0,
int pinpoint_only = 0) const; int pinpoint_only = 0) const;

View file

@ -3556,7 +3556,7 @@ bool OpaqueVal::DoUnserialize(UnserialInfo* info)
return true; return true;
} }
Val* check_and_promote(Val* v, const BroType* t, int is_init) Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* expr_location)
{ {
if ( ! v ) if ( ! v )
return 0; return 0;
@ -3580,7 +3580,7 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
if ( same_type(t, vt, is_init) ) if ( same_type(t, vt, is_init) )
return v; return v;
t->Error("type clash", v); t->Error("type clash", v, 0, expr_location);
Unref(v); Unref(v);
return 0; return 0;
} }
@ -3589,9 +3589,9 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
(! IsArithmetic(v_tag) || t_tag != TYPE_TIME || ! v->IsZero()) ) (! IsArithmetic(v_tag) || t_tag != TYPE_TIME || ! v->IsZero()) )
{ {
if ( t_tag == TYPE_LIST || v_tag == TYPE_LIST ) if ( t_tag == TYPE_LIST || v_tag == TYPE_LIST )
t->Error("list mixed with scalar", v); t->Error("list mixed with scalar", v, 0, expr_location);
else else
t->Error("arithmetic mixed with non-arithmetic", v); t->Error("arithmetic mixed with non-arithmetic", v, 0, expr_location);
Unref(v); Unref(v);
return 0; return 0;
} }
@ -3604,7 +3604,7 @@ Val* check_and_promote(Val* v, const BroType* t, int is_init)
TypeTag mt = max_type(t_tag, v_tag); TypeTag mt = max_type(t_tag, v_tag);
if ( mt != t_tag ) if ( mt != t_tag )
{ {
t->Error("over-promotion of arithmetic value", v); t->Error("over-promotion of arithmetic value", v, 0, expr_location);
Unref(v); Unref(v);
return 0; return 0;
} }

View file

@ -1219,7 +1219,7 @@ protected:
// Unref()'ing the original. If not a match, generates an error message // Unref()'ing the original. If not a match, generates an error message
// and returns nil, also Unref()'ing v. If is_init is true, then // and returns nil, also Unref()'ing v. If is_init is true, then
// the checking is done in the context of an initialization. // the checking is done in the context of an initialization.
extern Val* check_and_promote(Val* v, const BroType* t, int is_init); extern Val* check_and_promote(Val* v, const BroType* t, int is_init, const Location* expr_location = nullptr);
// Given a pointer to where a Val's core (i.e., its BRO value) resides, // Given a pointer to where a Val's core (i.e., its BRO value) resides,
// returns a corresponding newly-created or Ref()'d Val. ptr must already // returns a corresponding newly-created or Ref()'d Val. ptr must already